From 0d7d0ade0ea7fc9ea5156038ba1e680d4191dd36 Mon Sep 17 00:00:00 2001 From: Austin Birch Date: Thu, 30 Apr 2015 22:11:48 +0100 Subject: [PATCH 001/495] Basic implementation of target-based builds (needs tests) - Reads available targets out of all tools, if they supply a `targets` object - Allows you to select an `active` target - Allows you to trigger a build of the `active` target - Needs tests --- keymaps/build.json | 8 +++- lib/build.js | 102 ++++++++++++++++++++++++++++++++++++++-- lib/targets-view.js | 59 +++++++++++++++++++++++ lib/tools/atom-build.js | 30 ++++++++---- 4 files changed, 184 insertions(+), 15 deletions(-) create mode 100644 lib/targets-view.js diff --git a/keymaps/build.json b/keymaps/build.json index 45d38e4d..a39d378b 100644 --- a/keymaps/build.json +++ b/keymaps/build.json @@ -3,13 +3,17 @@ "cmd-alt-b": "build:trigger", "cmd-alt-v": "build:toggle-panel", "cmd-alt-g": "build:error-match", - "cmd-alt-h": "build:error-match-first" + "cmd-alt-h": "build:error-match-first", + "shift-alt-t": "build:select-active-target", + "alt-t": "build:build-active-target" }, ".platform-linux, .platform-win32": { "ctrl-alt-b": "build:trigger", "ctrl-alt-v": "build:toggle-panel", "ctrl-alt-g": "build:error-match", - "ctrl-alt-h": "build:error-match-first" + "ctrl-alt-h": "build:error-match-first", + "shift-alt-t": "build:select-active-target", + "alt-t": "build:build-active-target" }, ".build": { "escape": "build:stop" diff --git a/lib/build.js b/lib/build.js index e3ce31a6..7a1b496a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -7,6 +7,7 @@ var _ = require('lodash'); var XRegExp = require('xregexp').XRegExp; var SaveConfirmView = require('./save-confirm-view'); +var TargetsView = require('./targets-view'); var BuildView = require('./build-view'); var tools = require('./tools'); @@ -54,6 +55,16 @@ module.exports = { } }, + reservedCommands: [ + 'trigger', + 'stop', + 'confirm', + 'no-confirm', + 'error-match', + 'error-match-first', + 'select-active-targets' + ], + activate: function(state) { // Manually append /usr/local/bin as it may not be set on some systems, // and it's common to have node installed here. Keep it at end so it won't @@ -67,7 +78,10 @@ module.exports = { } this.buildView = new BuildView(); + this.cmd = {}; + this.targets = {}; + this.activeTarget = null; this.match = []; this.stdout = new Buffer(0); this.stderr = new Buffer(0); @@ -81,6 +95,12 @@ module.exports = { atom.commands.add('atom-workspace', 'build:no-confirm', function() { this.saveConfirmView.cancel(); }.bind(this)); + atom.commands.add('atom-workspace', 'build:select-active-target', function() { + this.selectActiveTarget(); + }.bind(this)); + atom.commands.add('atom-workspace', 'build:build-active-target', function() { + this.buildActiveTarget(); + }.bind(this)); atom.workspace.observeTextEditors(function(editor) { editor.onDidSave(function(event) { @@ -99,6 +119,74 @@ module.exports = { clearTimeout(this.finishedTimer); }, + refreshTargets: function() { + var path; + var textEditor = atom.workspace.getActiveTextEditor(); + if (!textEditor || !textEditor.getPath()) { + /* default to building the first one if no editor is active */ + path = atom.project.getPaths()[0]; + } else { + /* otherwise, build the one in the root of the active editor */ + path = _.find(atom.project.getPaths(), function (path) { + var realpath = fs.realpathSync(path); + return textEditor.getPath().substr(0, realpath.length) === realpath; + }); + } + + var cmd = { + env: {}, + args: [], + cwd: path, + sh: true, + errorMatch: '' + }; + + var targets = _.chain(tools) + .filter(function(tool) { + return tool.isEligable(path) + }) + .map(function(tool) { + var settings = tool.settings(path); + if (!settings.targets) { return null; } + return _.map(settings.targets, function(target, name) { + return [name, _.defaults(target, cmd)]; + }); + }) + .compact() + .flatten(true) + .value(); + + // turn the array of target descriptions into one object. Targets will be + // overwritten by later targets with the same name if present. + targets = _.reduce(targets, function(targets, target) { + targets[target[0]] = target[1]; + return targets; + }, {}); + + if (!_.isNull(this.activeTarget) && _.isUndefined(targets[this.activeTarget])) { + // our active target has been removed, so it is no longer valid + this.activeTarget = null; + } + + this.targets = targets; + return this.targets; + }, + + selectActiveTarget: function() { + var targets = this.refreshTargets(); + var targetNames = _.keys(targets); + var targetView = new TargetsView(); + targetView.show(targetNames, this.activeTarget, function(newTarget) { + this.activeTarget = newTarget; + }.bind(this)); + }, + + buildActiveTarget: function() { + // TODO: show an error if we have no active target? + if (_.isNull(this.activeTarget)) { return; } + this.build(this.activeTarget); + }, + buildCommand: function() { var path; var textEditor = atom.workspace.getActiveTextEditor(); @@ -203,11 +291,13 @@ module.exports = { this.match.push(this.match.shift()); }, - startNewBuild: function() { + startNew console.log('New active target'); + console.log(this.activeTarget); + function(targetName) { this.cmd = {}; this.match = []; try { - this.cmd = this.buildCommand(); + this.cmd = targetName ? this.targets[targetName] : this.buildCommand(); } catch (error) { this.buildView.reset(); this.buildView.errorMessage('You have a syntax error in your build file.', true); @@ -277,14 +367,16 @@ module.exports = { this.child.killed = true; }, - build: function() { + build: function(targetName) { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), function() { if (this.child) { - this.abort(this.startNewBuild.bind(this)); + this.abort(function() { + this.startNewBuild(targetName); + }.bind(this)); } else { - this.startNewBuild(); + this.startNewBuild(targetName); } }.bind(this)); }, diff --git a/lib/targets-view.js b/lib/targets-view.js new file mode 100644 index 00000000..1fe94ba1 --- /dev/null +++ b/lib/targets-view.js @@ -0,0 +1,59 @@ +'use strict'; + +var SelectListView = require('atom-space-pen-views').SelectListView; +var cscompatability = require('./cscompatability'); + +module.exports = (function() { + function TargetsView() { + SelectListView.apply(this, arguments); + } + + cscompatability.extends(TargetsView, SelectListView); + + TargetsView.prototype.initialize = function () { + TargetsView.__super__.initialize.apply(this, arguments); + this.list.addClass('mark-active'); + }; + + TargetsView.prototype.show = function(targets, activeTarget, cb) { + this.panel = atom.workspace.addModalPanel({ + item: this + }); + this.activeTarget = activeTarget; + this.callback = cb; + this.panel.show(); + this.setItems(targets); + this.focusFilterEditor(); + }; + + TargetsView.prototype.hide = function () { + this.panel.hide(); + }; + + TargetsView.prototype.viewForItem = function(targetName) { + var activeTarget = this.activeTarget; + return TargetsView.render(function() { + var activeClass = (targetName === activeTarget ? 'active' : ''); + this.li({class: activeClass}, targetName); + }); + }; + + TargetsView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) { + if (itemCount === 0) { + return 'No targets are specified in .atom-build.json'; + } else { + return 'No matches'; + } + }; + + TargetsView.prototype.confirmed = function(target) { + this.callback(target); + this.hide(); + }; + + TargetsView.prototype.cancelled = function() { + this.hide(); + }; + + return TargetsView; +})(); diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index 4ba67c35..39b27434 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -1,6 +1,7 @@ 'use strict'; var fs = require('fs'); +var _ = require('lodash'); module.exports.isEligable = function (path) { return fs.existsSync(path + '/.atom-build.json'); @@ -10,13 +11,26 @@ module.exports.settings = function (path) { var realAtomBuild = fs.realpathSync(path + '/.atom-build.json'); delete require.cache[realAtomBuild]; - var build = require(realAtomBuild); - return { - exec: build.cmd, - env: build.env, - args: build.args, - cwd: build.cwd, - sh: build.sh, - errorMatch: build.errorMatch + var createBuildConfig = function(build) { + return { + exec: build.cmd, + env: build.env, + args: build.args, + cwd: build.cwd, + sh: build.sh, + errorMatch: build.errorMatch + }; }; + + + var build = require(realAtomBuild); + var config = createBuildConfig(build); + + if (build.targets) { + config.targets = _.object(_.map(build.targets, function(target, name) { + return [name, createBuildConfig(target)]; + })); + } + + return config; }; From a6564e3f89dee5e2004a6f83461addd7a6cfdb46 Mon Sep 17 00:00:00 2001 From: Austin Birch Date: Thu, 30 Apr 2015 22:13:11 +0100 Subject: [PATCH 002/495] Fix whitespace: convert tabs->spaces --- lib/targets-view.js | 104 ++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/lib/targets-view.js b/lib/targets-view.js index 1fe94ba1..a08b1629 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -4,56 +4,56 @@ var SelectListView = require('atom-space-pen-views').SelectListView; var cscompatability = require('./cscompatability'); module.exports = (function() { - function TargetsView() { - SelectListView.apply(this, arguments); - } - - cscompatability.extends(TargetsView, SelectListView); - - TargetsView.prototype.initialize = function () { - TargetsView.__super__.initialize.apply(this, arguments); - this.list.addClass('mark-active'); - }; - - TargetsView.prototype.show = function(targets, activeTarget, cb) { - this.panel = atom.workspace.addModalPanel({ - item: this - }); - this.activeTarget = activeTarget; - this.callback = cb; - this.panel.show(); - this.setItems(targets); - this.focusFilterEditor(); - }; - - TargetsView.prototype.hide = function () { - this.panel.hide(); - }; - - TargetsView.prototype.viewForItem = function(targetName) { - var activeTarget = this.activeTarget; - return TargetsView.render(function() { - var activeClass = (targetName === activeTarget ? 'active' : ''); - this.li({class: activeClass}, targetName); - }); - }; - - TargetsView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) { - if (itemCount === 0) { - return 'No targets are specified in .atom-build.json'; - } else { - return 'No matches'; - } - }; - - TargetsView.prototype.confirmed = function(target) { - this.callback(target); - this.hide(); - }; - - TargetsView.prototype.cancelled = function() { - this.hide(); - }; - - return TargetsView; + function TargetsView() { + SelectListView.apply(this, arguments); + } + + cscompatability.extends(TargetsView, SelectListView); + + TargetsView.prototype.initialize = function () { + TargetsView.__super__.initialize.apply(this, arguments); + this.list.addClass('mark-active'); + }; + + TargetsView.prototype.show = function(targets, activeTarget, cb) { + this.panel = atom.workspace.addModalPanel({ + item: this + }); + this.activeTarget = activeTarget; + this.callback = cb; + this.panel.show(); + this.setItems(targets); + this.focusFilterEditor(); + }; + + TargetsView.prototype.hide = function () { + this.panel.hide(); + }; + + TargetsView.prototype.viewForItem = function(targetName) { + var activeTarget = this.activeTarget; + return TargetsView.render(function() { + var activeClass = (targetName === activeTarget ? 'active' : ''); + this.li({class: activeClass}, targetName); + }); + }; + + TargetsView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) { + if (itemCount === 0) { + return 'No targets are specified in .atom-build.json'; + } else { + return 'No matches'; + } + }; + + TargetsView.prototype.confirmed = function(target) { + this.callback(target); + this.hide(); + }; + + TargetsView.prototype.cancelled = function() { + this.hide(); + }; + + return TargetsView; })(); From f5e5bdb00f7c0ee6fc6895d7d33325e43f692335 Mon Sep 17 00:00:00 2001 From: Austin Birch Date: Fri, 1 May 2015 14:36:00 +0100 Subject: [PATCH 003/495] Fix accidental paste of console.log statements --- lib/build.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 7a1b496a..2bddf009 100644 --- a/lib/build.js +++ b/lib/build.js @@ -291,9 +291,7 @@ module.exports = { this.match.push(this.match.shift()); }, - startNew console.log('New active target'); - console.log(this.activeTarget); - function(targetName) { + startNewBuild: function(targetName) { this.cmd = {}; this.match = []; try { From 211686d5bf6dc1f88e426c93378c4ee663c69a42 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 5 May 2015 10:08:18 +0200 Subject: [PATCH 004/495] Error Match: Replace `cwd` properly When error matching, this is done relative to the current working directory. If the working directory is specified with a replacement variable (e.g. {FILE_ACTIVE}), it must be replaced properly so that the correct file is opened. --- lib/build.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/build.js b/lib/build.js index e3ce31a6..560266da 100644 --- a/lib/build.js +++ b/lib/build.js @@ -166,6 +166,13 @@ module.exports = { this.match = matchErr.concat(matchOut); }, + errorMatchGoTo: function () { + atom.workspace.open(this.replace(this.cmd.cwd) + path.sep + this.match[0].file, { + initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ + initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ + }); + + }, errorMatch: function() { if (!this.cmd.errorMatch) { return; @@ -178,11 +185,7 @@ module.exports = { } } - atom.workspace.open(this.cmd.cwd + path.sep + this.match[0].file, { - initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ - initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ - }); - + this.errorMatchGoTo(); this.match.push(this.match.shift()); }, @@ -195,11 +198,7 @@ module.exports = { return; } - atom.workspace.open(this.cmd.cwd + path.sep + this.match[0].file, { - initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ - initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ - }); - + this.errorMatchGoTo(); this.match.push(this.match.shift()); }, From 7f7467ad44a87748867a8a6003910ed2a532d6bd Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 5 May 2015 10:24:54 +0200 Subject: [PATCH 005/495] Travis: Speed up travis build Fetch less git refs for travis speed up --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 16cc42c5..4b1209ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,5 +17,7 @@ before_script: - npm install - npm test -script: - - 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh' +script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh' + +git: + depth: 10 From 2ad375c31f73165d76c5ff1e5b9c3c5f318777dc Mon Sep 17 00:00:00 2001 From: RomFouq Date: Thu, 7 May 2015 13:33:54 +0200 Subject: [PATCH 006/495] Add `stealFocus` in settings Add `stealFocus` in settings to choose whether the build panel should steal the focus or not. --- lib/build.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 560266da..feea83a2 100644 --- a/lib/build.js +++ b/lib/build.js @@ -34,6 +34,13 @@ module.exports = { default: false, order: 3 }, + stealFocus: { + title: 'Steal Focus', + description: 'Steal focus when opening build panel.', + type: 'boolean', + default: true, + order: 4 + }, monocleHeight: { title: 'Monocle Height', description: 'How much of the workspace to use for build panel when it is "maximized".', @@ -41,7 +48,7 @@ module.exports = { default: 0.75, minimum: 0.1, maximum: 0.9, - order: 4 + order: 5 }, minimizedHeight: { title: 'Minimized Height', @@ -50,7 +57,7 @@ module.exports = { default: 0.15, minimum: 0.1, maximum: 0.9, - order: 5 + order: 6 } }, From 1801b5d4e677f1a2804a72f9c5535ac1d2e33558 Mon Sep 17 00:00:00 2001 From: RomFouq Date: Thu, 7 May 2015 13:36:29 +0200 Subject: [PATCH 007/495] Use the `stealFocus` setting Read the setting when starting the build. --- lib/build-view.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 95b77bbd..c5c4d7e0 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -148,7 +148,9 @@ module.exports = (function() { BuildView.prototype.buildStarted = function() { this.reset(); this.attach(); - this.focus(); + if (atom.config.get('build.stealFocus')) { + this.focus(); + } this.updateTitle(); }; From bd3df0efec3be9a57fb0d523337a4196b6391a08 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 11 May 2015 19:59:33 +0200 Subject: [PATCH 008/495] Prepare 0.31.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94c22293..bb038742 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.30.0", + "version": "0.31.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From cb790a06b7d2ca3ec33ace7d678ad4ce9a72dc06 Mon Sep 17 00:00:00 2001 From: Mirko Hecky Date: Tue, 12 May 2015 14:49:48 +0200 Subject: [PATCH 009/495] Added changes to accept absolute error file path @see Readme.md --- README.md | 8 ++++++++ lib/build.js | 39 +++++++++++++++++---------------------- lib/tools/atom-build.js | 3 ++- package.json | 4 ++-- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 68df12c1..f3fd78ff 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ +This is a fork of the original [Build-Package](https://github.com/noseglid/atom-build) for Atom. + +# Changes to original Atom package +- Added `errorMatchPathAbsolute` option for `.atom-build.js`. If this is set to true, the path to the file which causes the error is interpreted as absolute path. +- Build command now searches for a build file in all root directories added to Atom. The first one that finds a build file is chosen. + +___ + # Atom Build package [![Build Travis](https://travis-ci.org/noseglid/atom-build.svg?branch=master)](https://travis-ci.org/noseglid/atom-build) [![Gitter chat](https://badges.gitter.im/noseglid/atom-build.svg)](https://gitter.im/noseglid/atom-build) diff --git a/lib/build.js b/lib/build.js index 560266da..e2ce4207 100644 --- a/lib/build.js +++ b/lib/build.js @@ -100,32 +100,27 @@ module.exports = { }, buildCommand: function() { - var path; - var textEditor = atom.workspace.getActiveTextEditor(); - if (!textEditor || !textEditor.getPath()) { - /* default to building the first one if no editor is active */ - path = atom.project.getPaths()[0]; - } else { - /* otherwise, build the one in the root of the active editor */ - path = _.find(atom.project.getPaths(), function (path) { - var realpath = fs.realpathSync(path); - return textEditor.getPath().substr(0, realpath.length) === realpath; - }); - } - var cmd = { env: {}, args: [], - cwd: path, + cwd: atom.project.getPaths()[0], sh: true, - errorMatch: '' + errorMatch: '', + errorMatchPathAbsolute: false }; - _.find(tools, function (tool) { - if (!tool.isEligable(path)) { - return; - } - cmd = _.defaults(tool.settings(path), cmd); - return true; + // Search for a folder in the project folders, that has at a + // build file in it (at least .atom-build.json). + _.find(atom.project.getPaths(), function(path) { + var found = false; + _.find(tools, function (tool) { + if (!tool.isEligable(path)) { + return; + } + cmd = _.defaults(tool.settings(path), cmd); + found = true; + return true; + }); + return found; }); return cmd; @@ -167,7 +162,7 @@ module.exports = { }, errorMatchGoTo: function () { - atom.workspace.open(this.replace(this.cmd.cwd) + path.sep + this.match[0].file, { + atom.workspace.open(!this.cmd.errorMatchPathAbsolute ? this.replace(this.cmd.cwd) + path.sep + this.match[0].file : this.match[0].file, { initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ }); diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index 4ba67c35..15562596 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -17,6 +17,7 @@ module.exports.settings = function (path) { args: build.args, cwd: build.cwd, sh: build.sh, - errorMatch: build.errorMatch + errorMatch: build.errorMatch, + errorMatchPathAbsolute: build.errorMatchPathAbsolute }; }; diff --git a/package.json b/package.json index bb038742..e83e074b 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "build", + "name": "build-2", "main": "./lib/build", "version": "0.31.0", "description": "Build your current project, directly from Atom", - "repository": "https://github.com/noseglid/atom-build", + "repository": "https://github.com/mirhec/atom-build", "license": "MIT", "engines": { "atom": ">=0.50.0" From 70effb957cad36fc97524b614c849e5de02dfa14 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 12 May 2015 20:31:21 +0200 Subject: [PATCH 010/495] Added Google Analytics Google Analytics helps keep track of how the package is used. This gives valuable information on what parts of the package to focus efforts on. All collected data is fully anonymous. It can also be opted out of if desired. --- .jshintrc | 2 ++ README.md | 17 ++++++++++++ lib/GoogleAnalytics.js | 59 +++++++++++++++++++++++++++++++++++++++++ lib/build-view.js | 3 +++ lib/build.js | 14 ++++++++++ lib/tools/Cargo.js | 2 ++ lib/tools/Elixir.js | 2 ++ lib/tools/Grunt.js | 2 ++ lib/tools/atom-build.js | 2 ++ lib/tools/gulp.js | 2 ++ lib/tools/make.js | 2 ++ lib/tools/npm_apm.js | 2 ++ package.json | 3 ++- 13 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 lib/GoogleAnalytics.js diff --git a/.jshintrc b/.jshintrc index 018d6b13..07eb92e9 100644 --- a/.jshintrc +++ b/.jshintrc @@ -20,6 +20,8 @@ "devel": true, // Define globals that are usually used for debugging: console, alert, etc. "globals": { // Define globals that are not defined per default "window": false, + "navigator": false, + "XMLHttpRequest": false, "document": false, "atom": false, "module": false, diff --git a/README.md b/README.md index 68df12c1..00f7e785 100644 --- a/README.md +++ b/README.md @@ -117,3 +117,20 @@ to cycle through the errors (in the order they appear, first on stderr then on s Often, the first error is the most interesting since other errors tend to be secondary faults caused by that first one. To jump to the first error you can use `cmd-alt-h` (OS X) or `ctrl-alt-h` (Linux/Windows) at any point to go to the first error. + +## Analytics + +The `atom-build` package uses google analytics to keep track of which features are in use +and at what frequency. This gives the maintainers a sense of what parts of the +package is most important and what parts can be removed. + +The data is fully anonymous and can not be tracked back to you in any way. +This is what is collected + + * Build triggered, succeeded or failed. + * Which build tool was used. + * Visibility of UI components. + +If you really do not want to share this information, you can opt out by disabling +the [metrics package](https://atom.io/packages/metrics). This will disable all analytics +collection, including the one from `atom-build`. diff --git a/lib/GoogleAnalytics.js b/lib/GoogleAnalytics.js new file mode 100644 index 00000000..5d0240c5 --- /dev/null +++ b/lib/GoogleAnalytics.js @@ -0,0 +1,59 @@ +'use strict'; + +var _ = require('lodash'); +var querystring = require('querystring'); +var cid = require('node-uuid').v4(); + +module.exports = (function () { + function GoogleAnalytics () {} + + GoogleAnalytics.sendEvent = function(category, action, label, value) { + var params = { + t: 'event', + ec: category, + ea: action + }; + if (label) { + params.el = label; + } + if (value) { + params.ev = value; + } + + GoogleAnalytics.send(params); + }; + + GoogleAnalytics.send = function (params) { + if (!atom.packages.getActivePackage('metrics')) { + // If the metrics package is disabled, then user has opted out. + return; + } + + _.extend(params, GoogleAnalytics.defaultParams()); + GoogleAnalytics.request('https://www.google-analytics.com/collect?' + querystring.stringify(params)); + }; + + GoogleAnalytics.request = function (url) { + if (!navigator.onLine) { + return; + } + GoogleAnalytics.post(url); + }; + + GoogleAnalytics.post = function (url) { + var xhr = new XMLHttpRequest(); + xhr.open('POST', url); + xhr.send(null); + }; + + GoogleAnalytics.defaultParams = function () { + // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters + return { + v: 1, + tid: 'UA-47615700-5', + cid: cid + }; + }; + + return GoogleAnalytics; +})(); diff --git a/lib/build-view.js b/lib/build-view.js index 95b77bbd..7aa57268 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -3,6 +3,7 @@ var _ = require('lodash'); var View = require('atom-space-pen-views').View; var cscompatability = require('./cscompatability'); +var GoogleAnalytics = require('./GoogleAnalytics'); var Convert = require('ansi-to-html'); module.exports = (function() { @@ -117,6 +118,7 @@ module.exports = (function() { }; BuildView.prototype.toggle = function(event, element) { + GoogleAnalytics.sendEvent('view', 'panel toggled'); this.isAttached() ? this.detach(true) : this.attach(true); }; @@ -135,6 +137,7 @@ module.exports = (function() { }; BuildView.prototype.toggleMonocle = function(event, element) { + GoogleAnalytics.sendEvent('view', 'monocle toggled'); if (!this.monocle) { this.setHeightPercent(atom.config.get('build.monocleHeight')); this.monocleButton.removeClass('icon-chevron-up').addClass('icon-chevron-down'); diff --git a/lib/build.js b/lib/build.js index 560266da..7cd151a5 100644 --- a/lib/build.js +++ b/lib/build.js @@ -8,6 +8,7 @@ var XRegExp = require('xregexp').XRegExp; var SaveConfirmView = require('./save-confirm-view'); var BuildView = require('./build-view'); +var GoogleAnalytics = require('./GoogleAnalytics'); var tools = require('./tools'); module.exports = { @@ -76,9 +77,11 @@ module.exports = { atom.commands.add('atom-workspace', 'build:error-match-first', this.errorMatchFirst.bind(this)); atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this)); atom.commands.add('atom-workspace', 'build:confirm', function() { + GoogleAnalytics.sendEvent('build', 'confirmed'); document.activeElement.click(); }); atom.commands.add('atom-workspace', 'build:no-confirm', function() { + GoogleAnalytics.sendEvent('build', 'not confirmed'); this.saveConfirmView.cancel(); }.bind(this)); @@ -90,9 +93,12 @@ module.exports = { } }); }); + + GoogleAnalytics.sendEvent('core', 'activated'); }, deactivate: function() { + GoogleAnalytics.sendEvent('core', 'deactivated'); if (this.child) { this.child.kill('SIGKILL'); } @@ -124,6 +130,7 @@ module.exports = { if (!tool.isEligable(path)) { return; } + GoogleAnalytics.sendEvent('build', 'tool selected', tool.niceName); cmd = _.defaults(tool.settings(path), cmd); return true; }); @@ -174,6 +181,7 @@ module.exports = { }, errorMatch: function() { + GoogleAnalytics.sendEvent('errorMatch', 'match'); if (!this.cmd.errorMatch) { return; } @@ -190,6 +198,7 @@ module.exports = { }, errorMatchFirst: function() { + GoogleAnalytics.sendEvent('errorMatch', 'first'); if (!this.cmd.errorMatch) { return; } @@ -214,6 +223,8 @@ module.exports = { return; } + GoogleAnalytics.sendEvent('build', 'triggered'); + if (!this.cmd.exec) { return; } @@ -253,9 +264,12 @@ module.exports = { this.child.on('close', function(exitCode) { this.buildView.buildFinished(0 === exitCode); if (0 === exitCode) { + GoogleAnalytics.sendEvent('build', 'succeeded'); this.finishedTimer = setTimeout(function() { this.buildView.detach(); }.bind(this), 1000); + } else { + GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; }.bind(this)); diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js index a64d8152..a136769f 100644 --- a/lib/tools/Cargo.js +++ b/lib/tools/Cargo.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'Cargo'; + module.exports.isEligable = function (path) { return fs.existsSync(path + '/Cargo.toml'); }; diff --git a/lib/tools/Elixir.js b/lib/tools/Elixir.js index c4fe402a..a30b2ac2 100644 --- a/lib/tools/Elixir.js +++ b/lib/tools/Elixir.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'Elixir'; + module.exports.isEligable = function (path) { return fs.existsSync(path + '/mix.exs'); }; diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 0ce41750..a2feab62 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'Grunt'; + module.exports.isEligable = function (path) { return fs.existsSync(path + '/Gruntfile.js'); }; diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index 4ba67c35..90aab630 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'Custom file (.atom-build.json)'; + module.exports.isEligable = function (path) { return fs.existsSync(path + '/.atom-build.json'); }; diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 96739c7a..1e61cc49 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'gulp'; + module.exports.isEligable = function (path) { return fs.existsSync(path + '/gulpfile.js'); }; diff --git a/lib/tools/make.js b/lib/tools/make.js index 9a56bfb4..89c2ca00 100644 --- a/lib/tools/make.js +++ b/lib/tools/make.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'GNU Make'; + module.exports.isEligable = function (path) { return fs.existsSync(path + '/Makefile'); }; diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index 43865b37..52047578 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -2,6 +2,8 @@ var fs = require('fs'); +module.exports.niceName = 'npm or apm'; + module.exports.isEligable = function (path) { if (!fs.existsSync(path + '/package.json')) { return false; diff --git a/package.json b/package.json index bb038742..6aa13229 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "temp": "^0.8.1", "fs-plus": "^2.4.0", "atom-space-pen-views": "^2.0.3", - "xregexp": "^2.0.0" + "xregexp": "^2.0.0", + "node-uuid": "^1.4.3" }, "devDependencies": { "jshint": "^2.5.11", From 5a5cb8304e0befa2b14829659723f91bfe97a7da Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 12 May 2015 21:18:40 +0200 Subject: [PATCH 011/495] Prepare 0.32.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6aa13229..64701bd3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.31.0", + "version": "0.32.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 204dc90ac7eb0b798008b93efa405c8424bdcc42 Mon Sep 17 00:00:00 2001 From: Mirko Hecky Date: Wed, 13 May 2015 09:50:19 +0200 Subject: [PATCH 012/495] Removed unnecessary changes. I noticed that the changes I made to find the `.atom-build.json` file was not necessary, so I removed it. --- README.md | 8 -------- lib/build.js | 34 ++++++++++++++++++++-------------- package.json | 4 ++-- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f3fd78ff..68df12c1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,3 @@ -This is a fork of the original [Build-Package](https://github.com/noseglid/atom-build) for Atom. - -# Changes to original Atom package -- Added `errorMatchPathAbsolute` option for `.atom-build.js`. If this is set to true, the path to the file which causes the error is interpreted as absolute path. -- Build command now searches for a build file in all root directories added to Atom. The first one that finds a build file is chosen. - -___ - # Atom Build package [![Build Travis](https://travis-ci.org/noseglid/atom-build.svg?branch=master)](https://travis-ci.org/noseglid/atom-build) [![Gitter chat](https://badges.gitter.im/noseglid/atom-build.svg)](https://gitter.im/noseglid/atom-build) diff --git a/lib/build.js b/lib/build.js index e2ce4207..4e0f54b9 100644 --- a/lib/build.js +++ b/lib/build.js @@ -100,27 +100,33 @@ module.exports = { }, buildCommand: function() { + var path; + var textEditor = atom.workspace.getActiveTextEditor(); + if (!textEditor || !textEditor.getPath()) { + /* default to building the first one if no editor is active */ + path = atom.project.getPaths()[0]; + } else { + /* otherwise, build the one in the root of the active editor */ + path = _.find(atom.project.getPaths(), function (path) { + var realpath = fs.realpathSync(path); + return textEditor.getPath().substr(0, realpath.length) === realpath; + }); + } + var cmd = { env: {}, args: [], - cwd: atom.project.getPaths()[0], + cwd: path, sh: true, errorMatch: '', errorMatchPathAbsolute: false }; - // Search for a folder in the project folders, that has at a - // build file in it (at least .atom-build.json). - _.find(atom.project.getPaths(), function(path) { - var found = false; - _.find(tools, function (tool) { - if (!tool.isEligable(path)) { - return; - } - cmd = _.defaults(tool.settings(path), cmd); - found = true; - return true; - }); - return found; + _.find(tools, function (tool) { + if (!tool.isEligable(path)) { + return; + } + cmd = _.defaults(tool.settings(path), cmd); + return true; }); return cmd; diff --git a/package.json b/package.json index e83e074b..bb038742 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "build-2", + "name": "build", "main": "./lib/build", "version": "0.31.0", "description": "Build your current project, directly from Atom", - "repository": "https://github.com/mirhec/atom-build", + "repository": "https://github.com/noseglid/atom-build", "license": "MIT", "engines": { "atom": ">=0.50.0" From 57e9d0ad54c526a5b8635e21fb1de9e767b8c15a Mon Sep 17 00:00:00 2001 From: Mirko Hecky Date: Wed, 13 May 2015 14:45:35 +0200 Subject: [PATCH 013/495] Removed `errorMatchPathAbsolute` parameter and added `absFile` regex argument that is taken if no `file` argument is specified. --- lib/build.js | 9 ++++++--- lib/tools/atom-build.js | 3 +-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/build.js b/lib/build.js index e550bf47..1496f3e1 100644 --- a/lib/build.js +++ b/lib/build.js @@ -124,8 +124,7 @@ module.exports = { args: [], cwd: path, sh: true, - errorMatch: '', - errorMatchPathAbsolute: false + errorMatch: '' }; _.find(tools, function (tool) { if (!tool.isEligable(path)) { @@ -175,7 +174,11 @@ module.exports = { }, errorMatchGoTo: function () { - atom.workspace.open(!this.cmd.errorMatchPathAbsolute ? this.replace(this.cmd.cwd) + path.sep + this.match[0].file : this.match[0].file, { + var file = this.replace(this.cmd.cwd) + path.sep + this.match[0].file; + if(!this.match[0].file) + file = this.match[0].absFile; + console.log(file); + atom.workspace.open(file, { initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ }); diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index 7cf2417c..90aab630 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -19,7 +19,6 @@ module.exports.settings = function (path) { args: build.args, cwd: build.cwd, sh: build.sh, - errorMatch: build.errorMatch, - errorMatchPathAbsolute: build.errorMatchPathAbsolute + errorMatch: build.errorMatch }; }; From dae61344aeaf60ab14c1d39e951a8a75ce2c0fcf Mon Sep 17 00:00:00 2001 From: Mirko Hecky Date: Wed, 13 May 2015 14:50:53 +0200 Subject: [PATCH 014/495] Removed debugging output. --- lib/build.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 1496f3e1..c29e9094 100644 --- a/lib/build.js +++ b/lib/build.js @@ -176,8 +176,7 @@ module.exports = { errorMatchGoTo: function () { var file = this.replace(this.cmd.cwd) + path.sep + this.match[0].file; if(!this.match[0].file) - file = this.match[0].absFile; - console.log(file); + file = this.match[0].absFile; atom.workspace.open(file, { initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ From ccdc9c9c9e2e1f7384e621eccd4207113eca06fd Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 14 May 2015 10:57:01 +0200 Subject: [PATCH 015/495] GoogleAnalytics: Unique cid per user Instead of generating a new cid everytime `build` launches, make it dependant on the computer (the MAC address), so it is the same for each user (in reality each computer). The MAC is hashed before sent so it can not be used for tracing. --- lib/GoogleAnalytics.js | 23 +++++++++++++++++++---- package.json | 3 ++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/GoogleAnalytics.js b/lib/GoogleAnalytics.js index 5d0240c5..64a9a94a 100644 --- a/lib/GoogleAnalytics.js +++ b/lib/GoogleAnalytics.js @@ -2,11 +2,25 @@ var _ = require('lodash'); var querystring = require('querystring'); -var cid = require('node-uuid').v4(); +var cid; module.exports = (function () { function GoogleAnalytics () {} + GoogleAnalytics.getCid = function (cb) { + if (cid) { + return cb(cid); + } + + require('getmac').getMac(function(error, macAddress) { + if (error) { + return cb(cid = require('node-uuid').v4()); + } + + return cb(require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex')); + }); + }; + GoogleAnalytics.sendEvent = function(category, action, label, value) { var params = { t: 'event', @@ -29,8 +43,10 @@ module.exports = (function () { return; } - _.extend(params, GoogleAnalytics.defaultParams()); - GoogleAnalytics.request('https://www.google-analytics.com/collect?' + querystring.stringify(params)); + GoogleAnalytics.getCid(function (cid) { + _.extend(params, { cid: cid }, GoogleAnalytics.defaultParams()); + GoogleAnalytics.request('https://www.google-analytics.com/collect?' + querystring.stringify(params)); + }); }; GoogleAnalytics.request = function (url) { @@ -51,7 +67,6 @@ module.exports = (function () { return { v: 1, tid: 'UA-47615700-5', - cid: cid }; }; diff --git a/package.json b/package.json index 64701bd3..076fa5ff 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "fs-plus": "^2.4.0", "atom-space-pen-views": "^2.0.3", "xregexp": "^2.0.0", - "node-uuid": "^1.4.3" + "node-uuid": "^1.4.3", + "getmac": "^1.0.7" }, "devDependencies": { "jshint": "^2.5.11", From 65fa279c915c885b68c624e27dde37bf40d2a112 Mon Sep 17 00:00:00 2001 From: Mirko Hecky Date: Thu, 14 May 2015 20:41:53 +0200 Subject: [PATCH 016/495] Fixed code style --- lib/build.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index c29e9094..5cc35348 100644 --- a/lib/build.js +++ b/lib/build.js @@ -175,8 +175,9 @@ module.exports = { errorMatchGoTo: function () { var file = this.replace(this.cmd.cwd) + path.sep + this.match[0].file; - if(!this.match[0].file) + if (!this.match[0].file) { file = this.match[0].absFile; + } atom.workspace.open(file, { initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ From f89d39d859167e7aea9ab996ecce61c4d5e94c1a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 15 May 2015 19:47:16 +0200 Subject: [PATCH 017/495] Removed migration code --- lib/build.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/build.js b/lib/build.js index 7cd151a5..a43e060a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -61,12 +61,6 @@ module.exports = { // accidentially override any other node installation process.env.PATH += ':/usr/local/bin'; - /* Migration from 0.29.0. Remove after next version */ - if (atom.config.get('build.keepVisible')) { - atom.config.set('build.panelVisibility', 'Keep Visible'); - atom.config.unset('build.keepVisible'); - } - this.buildView = new BuildView(); this.cmd = {}; this.match = []; From 49accd3d4467cfdf603728c9526815ad5eef7462 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 17 May 2015 18:02:30 +0200 Subject: [PATCH 018/495] Prepare 0.33.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 076fa5ff..5d8b7e09 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.32.0", + "version": "0.33.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 0be160e3ac8cebefb186b83d79cbbf053e2ce1c2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 10:52:16 +0200 Subject: [PATCH 019/495] Error Match: If file doesn't exists. Give useful error Also refactors some specs to separate files to keep `build-spec.js` smaller. --- lib/build.js | 21 +- spec/build-confirm-spec.js | 229 +++++++++++ spec/build-error-match-spec.js | 240 ++++++++++++ spec/build-spec.js | 364 ------------------ .../.atom-build.error-match-no-file.json | 4 + 5 files changed, 490 insertions(+), 368 deletions(-) create mode 100644 spec/build-confirm-spec.js create mode 100644 spec/build-error-match-spec.js create mode 100644 spec/fixture/.atom-build.error-match-no-file.json diff --git a/lib/build.js b/lib/build.js index a43e060a..f96f229a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -168,12 +168,25 @@ module.exports = { }, errorMatchGoTo: function () { - atom.workspace.open(this.replace(this.cmd.cwd) + path.sep + this.match[0].file, { - initialLine: this.match[0].line ? this.match[0].line - 1 : 0, /* Because atom is zero-based */ - initialColumn: this.match[0].col ? this.match[0].col - 1 : 0 /* Because atom is zero-based */ - }); + var file = this.replace(this.cmd.cwd) + path.sep + this.match[0].file; + var row = this.match[0].line ? this.match[0].line - 1 : 0; /* Because atom is zero-based */ + var col = this.match[0].col ? this.match[0].col - 1 : 0; /* Because atom is zero-based */ + + fs.exists(file, function (exists) { + if (!exists) { + this.buildView.reset(); + this.buildView.errorMessage('Error matching failed:', true); + this.buildView.append('Matched file does not exist: ' + file); + return; + } + atom.workspace.open(file, { + initialLine: row, + initialColumn: col + }); + }.bind(this)); }, + errorMatch: function() { GoogleAnalytics.sendEvent('errorMatch', 'match'); if (!this.cmd.errorMatch) { diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js new file mode 100644 index 00000000..f0f2a0de --- /dev/null +++ b/spec/build-confirm-spec.js @@ -0,0 +1,229 @@ +var _ = require('lodash'); +var fs = require('fs-plus'); +var temp = require('temp'); + +describe('Build', function() { + 'use strict'; + + var goodMakefile = __dirname + '/fixture/Makefile.good'; + + var directory = null; + var workspaceElement = null; + + temp.track(); + + beforeEach(function() { + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + atom.project.setPaths([ directory ]); + + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + + runs(function() { + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + }); + + waitsForPromise(function() { + return atom.packages.activatePackage('build'); + }); + }); + + afterEach(function() { + fs.removeSync(directory); + }); + + describe('when the text editor is modified', function() { + it('should show the save confirmation', function() { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + // console.log('writing makefile'); + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + // console.log('testing if makefile is open'); + return atom.workspace.open('Makefile'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + // console.log('adding text'); + editor.insertText('hello kansas'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + // console.log('checking for focused element'); + return workspaceElement.querySelector(':focus'); + }); + + runs(function() { + // console.log('verifying that success is the focuesed element'); + expect(workspaceElement.querySelector('.btn-success:focus')).toExist(); + }); + }); + + it('should cancel the confirm window when pressing escape', function() { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + return atom.workspace.open('Makefile'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + editor.insertText('hello kansas'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector(':focus'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:no-confirm'); + expect(workspaceElement.querySelector('.btn-success:focus')).not.toExist(); + }); + }); + + it('should not confirm if a TextEditor edits an unsaved file', function() { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + return atom.workspace.open('Makefile'); + }); + + waitsForPromise(function() { + return atom.workspace.open(); + }); + + runs(function() { + var editor = _.find(atom.workspace.getTextEditors(), function(textEditor) { + return ('untitled' === textEditor.getTitle()); + }); + editor.insertText('Just some temporary place to write stuff'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); + }); + }); + + it('should save and build when selecting save and build', function() { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + return atom.workspace.open('Makefile'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + editor.insertText('dummy:\n\techo kansas\n'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector(':focus'); + }); + + runs(function() { + workspaceElement.querySelector(':focus').click(); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/kansas/); + expect(!editor.isModified()); + }); + }); + + it('should build but not save when opting so', function() { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + return atom.workspace.open('Makefile'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + editor.insertText('dummy:\n\techo kansas\n'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector(':focus'); + }); + + runs(function() { + workspaceElement.querySelector('button[click="confirmWithoutSave"]').click(); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').innerHTML).not.toMatch(/kansas/); + expect(editor.isModified()); + }); + }); + + it('should do nothing when cancelling', function() { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + return atom.workspace.open('Makefile'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + editor.insertText('dummy:\n\techo kansas\n'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector(':focus'); + }); + + runs(function() { + workspaceElement.querySelector('button[click="cancel"]').click(); + }); + + waits(2); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + expect(workspaceElement.querySelector('.build')).not.toExist(); + expect(editor.isModified()); + }); + }); + }); + +}); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js new file mode 100644 index 00000000..13890262 --- /dev/null +++ b/spec/build-error-match-spec.js @@ -0,0 +1,240 @@ +var fs = require('fs-plus'); +var temp = require('temp'); + +describe('Build', function() { + 'use strict'; + + var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; + var errorMatchNoFileBuildFile = __dirname + '/fixture/.atom-build.error-match-no-file.json'; + var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; + var errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json'; + var errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; + + var directory = null; + var workspaceElement = null; + + temp.track(); + + beforeEach(function() { + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + atom.project.setPaths([ directory ]); + + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + + runs(function() { + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + }); + + waitsForPromise(function() { + return atom.packages.activatePackage('build'); + }); + }); + + afterEach(function() { + fs.removeSync(directory); + }); + + describe('when output is captured to show editor on error', function () { + it('should place the line and column on error in correct file', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + }); + }); + + it('should give an error if matched file does not exist', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNoFileBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').textContent === 'Error matching failed:'; + }); + + runs(function() { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Matched file does not exist: .+black-hole/); + }); + }); + + it('should open just the file if line and column is not available', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNLCAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + }); + }); + + it('should cycle through the file if multiple error occurred', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + atom.workspace.getActivePane().destroyActiveItem(); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(1); + expect(bufferPosition.column).toEqual(4); + atom.workspace.getActivePane().destroyActiveItem(); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + }); + }); + + it('should jump to first error', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiFirstAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match-first'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + atom.workspace.getActivePane().destroyActiveItem(); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(1); + expect(bufferPosition.column).toEqual(4); + atom.workspace.getActivePane().destroyActiveItem(); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match-first'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + }); + }); + }); +}); diff --git a/spec/build-spec.js b/spec/build-spec.js index 3ce735d7..d0f5d210 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,7 +1,6 @@ var fs = require('fs-plus'); var path = require('path'); var temp = require('temp'); -var _ = require('lodash'); describe('Build', function() { 'use strict'; @@ -22,10 +21,6 @@ describe('Build', function() { var shTrueAtomBuildFile = __dirname + '/fixture/.atom-build.sh-true.json'; var shDefaultAtomBuildFile = __dirname + '/fixture/.atom-build.sh-default.json'; var syntaxErrorAtomBuildFile = __dirname + '/fixture/.atom-build.syntax-error.json'; - var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; - var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; - var errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json'; - var errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; var directory = null; var workspaceElement = null; @@ -538,190 +533,6 @@ describe('Build', function() { }); }); - describe('when the text editor is modified', function() { - it('should show the save confirmation', function() { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - waitsForPromise(function() { - return atom.workspace.open('Makefile'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('hello kansas'); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector(':focus'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.btn-success:focus')).toExist(); - }); - }); - - it('should cancel the confirm window when pressing escape', function() { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - waitsForPromise(function() { - return atom.workspace.open('Makefile'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('hello kansas'); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector(':focus'); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:no-confirm'); - expect(workspaceElement.querySelector('.btn-success:focus')).not.toExist(); - }); - }); - - it('should not confirm if a TextEditor edits an unsaved file', function() { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - waitsForPromise(function() { - return atom.workspace.open('Makefile'); - }); - - waitsForPromise(function() { - return atom.workspace.open(); - }); - - runs(function() { - var editor = _.find(atom.workspace.getTextEditors(), function(textEditor) { - return ('untitled' === textEditor.getTitle()); - }); - editor.insertText('Just some temporary place to write stuff'); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); - }); - }); - - it('should save and build when selecting save and build', function() { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - waitsForPromise(function() { - return atom.workspace.open('Makefile'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('dummy:\n\techo kansas\n'); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector(':focus'); - }); - - runs(function() { - workspaceElement.querySelector(':focus').click(); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/kansas/); - expect(!editor.isModified()); - }); - }); - - it('should build but not save when opting so', function() { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - waitsForPromise(function() { - return atom.workspace.open('Makefile'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('dummy:\n\techo kansas\n'); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector(':focus'); - }); - - runs(function() { - workspaceElement.querySelector('button[click="confirmWithoutSave"]').click(); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').innerHTML).not.toMatch(/kansas/); - expect(editor.isModified()); - }); - }); - - it('should do nothing when cancelling', function() { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - waitsForPromise(function() { - return atom.workspace.open('Makefile'); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('dummy:\n\techo kansas\n'); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector(':focus'); - }); - - runs(function() { - workspaceElement.querySelector('button[click="cancel"]').click(); - }); - - waits(2); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - expect(workspaceElement.querySelector('.build')).not.toExist(); - expect(editor.isModified()); - }); - }); - }); - describe('when the text editor is saved', function() { it('should build when buildOnSave is true', function() { atom.config.set('build.buildOnSave', true); @@ -768,181 +579,6 @@ describe('Build', function() { }); }); - describe('when output is captured to show editor on error', function () { - it('should place the line and column on error in correct file', function () { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(2); - expect(bufferPosition.column).toEqual(7); - }); - }); - - it('should open just the file if line and column is not available', function () { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNLCAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - }); - }); - - it('should cycle through the file if multiple error occurred', function () { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(2); - expect(bufferPosition.column).toEqual(7); - atom.workspace.getActivePane().destroyActiveItem(); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(1); - expect(bufferPosition.column).toEqual(4); - atom.workspace.getActivePane().destroyActiveItem(); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(2); - expect(bufferPosition.column).toEqual(7); - }); - }); - - it('should jump to first error', function () { - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - - fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiFirstAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match-first'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(2); - expect(bufferPosition.column).toEqual(7); - atom.workspace.getActivePane().destroyActiveItem(); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(1); - expect(bufferPosition.column).toEqual(4); - atom.workspace.getActivePane().destroyActiveItem(); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:error-match-first'); - }); - - waitsFor(function() { - return atom.workspace.getActiveTextEditor(); - }); - - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); - expect(editor.getTitle()).toEqual('.atom-build.json'); - expect(bufferPosition.row).toEqual(2); - expect(bufferPosition.column).toEqual(7); - }); - }); - }); - describe('when multiple project roots are open', function () { it('should run the second root if a file there is active', function () { var directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; diff --git a/spec/fixture/.atom-build.error-match-no-file.json b/spec/fixture/.atom-build.error-match-no-file.json new file mode 100644 index 00000000..5ddcd05c --- /dev/null +++ b/spec/fixture/.atom-build.error-match-no-file.json @@ -0,0 +1,4 @@ +{ + "cmd": "echo 'file:black-hole,line:3,column:8' && return 1", + "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)" +} \ No newline at end of file From 3b6e65a75174576dcf320e212d8d1230a614a457 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 11:19:28 +0200 Subject: [PATCH 020/495] README: error matching and `absFile`. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 00f7e785..4dc8222b 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,8 @@ and has the syntax for named groups: `(? RE )` where `name` would be the n matched by the regular expression `RE`. The following named groups can be matched from the output: - * `file` - **[required]** the file to open. `(? RE)`. + * `file` - **[required if not `absFile` is set]** the file to open. `(? RE)`. + * `absFile` - **[required if not `file` is set]** the absolute path to file. `(? RE)`. * `line` - **[optional]** the line the error resides on. `(? RE)`. * `col` - **[optional]** the column the error resides on. `(? RE)`. From 672a31b35761c23ae876bcdb9f16016340f601c9 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 11:36:23 +0200 Subject: [PATCH 021/495] Spec: Added test for errorMatching with absFile --- spec/build-error-match-spec.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 13890262..ee17cef4 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -236,5 +236,32 @@ describe('Build', function() { expect(bufferPosition.column).toEqual(7); }); }); + + it('should open the absolute file if absFile is set', function () { + var atomBuild = { + cmd: 'echo __' + directory + '.atom-build.json__ && return 1', + errorMatch: '__(?.+)__' + }; + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify(atomBuild)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + return atom.commands.dispatch(workspaceElement, 'build:error-match-first'); + }); + + waitsFor(function () { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + expect(editor.getPath()).toEqual(directory + '.atom-build.json'); + }); + + }); }); }); From 5a234d6888b208572b62f756ec94d3560efb40b6 Mon Sep 17 00:00:00 2001 From: Austin Birch Date: Mon, 18 May 2015 13:43:20 +0100 Subject: [PATCH 022/495] Build command now builds the last active target --- keymaps/build.json | 3 +-- lib/build.js | 23 +++++++---------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/keymaps/build.json b/keymaps/build.json index a39d378b..b6cdba99 100644 --- a/keymaps/build.json +++ b/keymaps/build.json @@ -4,8 +4,7 @@ "cmd-alt-v": "build:toggle-panel", "cmd-alt-g": "build:error-match", "cmd-alt-h": "build:error-match-first", - "shift-alt-t": "build:select-active-target", - "alt-t": "build:build-active-target" + "shift-alt-t": "build:select-active-target" }, ".platform-linux, .platform-win32": { "ctrl-alt-b": "build:trigger", diff --git a/lib/build.js b/lib/build.js index 2bddf009..f516437d 100644 --- a/lib/build.js +++ b/lib/build.js @@ -98,9 +98,6 @@ module.exports = { atom.commands.add('atom-workspace', 'build:select-active-target', function() { this.selectActiveTarget(); }.bind(this)); - atom.commands.add('atom-workspace', 'build:build-active-target', function() { - this.buildActiveTarget(); - }.bind(this)); atom.workspace.observeTextEditors(function(editor) { editor.onDidSave(function(event) { @@ -143,7 +140,7 @@ module.exports = { var targets = _.chain(tools) .filter(function(tool) { - return tool.isEligable(path) + return tool.isEligable(path); }) .map(function(tool) { var settings = tool.settings(path); @@ -177,16 +174,10 @@ module.exports = { var targetNames = _.keys(targets); var targetView = new TargetsView(); targetView.show(targetNames, this.activeTarget, function(newTarget) { - this.activeTarget = newTarget; + this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; }.bind(this)); }, - buildActiveTarget: function() { - // TODO: show an error if we have no active target? - if (_.isNull(this.activeTarget)) { return; } - this.build(this.activeTarget); - }, - buildCommand: function() { var path; var textEditor = atom.workspace.getActiveTextEditor(); @@ -291,11 +282,11 @@ module.exports = { this.match.push(this.match.shift()); }, - startNewBuild: function(targetName) { + startNewBuild: function() { this.cmd = {}; this.match = []; try { - this.cmd = targetName ? this.targets[targetName] : this.buildCommand(); + this.cmd = this.activeTarget ? this.targets[this.activeTarget] : this.buildCommand(); } catch (error) { this.buildView.reset(); this.buildView.errorMessage('You have a syntax error in your build file.', true); @@ -365,16 +356,16 @@ module.exports = { this.child.killed = true; }, - build: function(targetName) { + build: function() { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), function() { if (this.child) { this.abort(function() { - this.startNewBuild(targetName); + this.startNewBuild(); }.bind(this)); } else { - this.startNewBuild(targetName); + this.startNewBuild(); } }.bind(this)); }, From 7a0c4f52299a09435cf64b20f5fb6f65d8c67303 Mon Sep 17 00:00:00 2001 From: Austin Birch Date: Mon, 18 May 2015 14:03:11 +0100 Subject: [PATCH 023/495] Concise abort param --- lib/build.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 08984bfb..14820fad 100644 --- a/lib/build.js +++ b/lib/build.js @@ -384,9 +384,7 @@ module.exports = { this.doSaveConfirm(this.unsavedTextEditors(), function() { if (this.child) { - this.abort(function() { - this.startNewBuild(); - }.bind(this)); + this.abort(this.startNewBuild.bind(this)); } else { this.startNewBuild(); } From 399931d6a00065a747cfd7813947e2f2a2a66fec Mon Sep 17 00:00:00 2001 From: Austin Birch Date: Mon, 18 May 2015 14:04:44 +0100 Subject: [PATCH 024/495] Remove reserved commands list as we are no longer binding dynamically named commands --- lib/build.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/build.js b/lib/build.js index 14820fad..580316f5 100644 --- a/lib/build.js +++ b/lib/build.js @@ -56,16 +56,6 @@ module.exports = { } }, - reservedCommands: [ - 'trigger', - 'stop', - 'confirm', - 'no-confirm', - 'error-match', - 'error-match-first', - 'select-active-targets' - ], - activate: function(state) { // Manually append /usr/local/bin as it may not be set on some systems, // and it's common to have node installed here. Keep it at end so it won't From 0d70cdd149f618dc9d7c2dc7919ee2b78577cafe Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 19:14:10 +0200 Subject: [PATCH 025/495] Fixed code style hint --- lib/targets-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/targets-view.js b/lib/targets-view.js index a08b1629..42a3ba7b 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -34,7 +34,7 @@ module.exports = (function() { var activeTarget = this.activeTarget; return TargetsView.render(function() { var activeClass = (targetName === activeTarget ? 'active' : ''); - this.li({class: activeClass}, targetName); + this.li({ class: activeClass }, targetName); }); }; From 8ae25ba058630ec0859554c265c1507a436d4420 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 19:33:10 +0200 Subject: [PATCH 026/495] Select active targets with cmd-alt-t/ctrl-alt-t --- README.md | 1 + keymaps/build.json | 9 ++++----- lib/build.js | 4 +--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4dc8222b..05550a19 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Automatically build your project inside your new favorite editor, Atom. * `cmd-alt-g` / `ctrl-alt-g` cycles through causes of build error. See [Error Matching](#error-match). * `cmd-alt-h` / `ctrl-alt-h` goes to the first build error. See [Error Matching](#error-match). * `cmd-alt-v` / `ctrl-alt-v` Toggles the build panel. + * `cmd-alt-t` / `ctrl-alt-t` Displays the available build targets. * `escape` terminates build / closes the build window. ![work work](https://noseglid.github.io/atom-build.gif) diff --git a/keymaps/build.json b/keymaps/build.json index b6cdba99..46e1fdeb 100644 --- a/keymaps/build.json +++ b/keymaps/build.json @@ -1,18 +1,17 @@ { - ".platform-darwin": { + ".platform-darwin atom-workspace": { "cmd-alt-b": "build:trigger", "cmd-alt-v": "build:toggle-panel", "cmd-alt-g": "build:error-match", "cmd-alt-h": "build:error-match-first", - "shift-alt-t": "build:select-active-target" + "cmd-alt-t": "build:select-active-target" }, - ".platform-linux, .platform-win32": { + ".platform-linux atom-workspace, .platform-win32 atom-workspace": { "ctrl-alt-b": "build:trigger", "ctrl-alt-v": "build:toggle-panel", "ctrl-alt-g": "build:error-match", "ctrl-alt-h": "build:error-match-first", - "shift-alt-t": "build:select-active-target", - "alt-t": "build:build-active-target" + "ctrl-alt-t": "build:select-active-target" }, ".build": { "escape": "build:stop" diff --git a/lib/build.js b/lib/build.js index 580316f5..720bce52 100644 --- a/lib/build.js +++ b/lib/build.js @@ -82,9 +82,7 @@ module.exports = { GoogleAnalytics.sendEvent('build', 'not confirmed'); this.saveConfirmView.cancel(); }.bind(this)); - atom.commands.add('atom-workspace', 'build:select-active-target', function() { - this.selectActiveTarget(); - }.bind(this)); + atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); atom.workspace.observeTextEditors(function(editor) { editor.onDidSave(function(event) { From c98a51ff832f239d1c1b1a85464896cc10644bdb Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 19:33:30 +0200 Subject: [PATCH 027/495] Trigger build when selecting target --- lib/build.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/build.js b/lib/build.js index 720bce52..c5cee50f 100644 --- a/lib/build.js +++ b/lib/build.js @@ -163,6 +163,9 @@ module.exports = { var targetView = new TargetsView(); targetView.show(targetNames, this.activeTarget, function(newTarget) { this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; + + var workspaceElement = atom.views.getView(atom.workspace); + atom.commands.dispatch(workspaceElement, 'build:trigger'); }.bind(this)); }, From 87bf1741cf1f14d80c8a465c32e7a7fe7e9de8ff Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 22:59:02 +0200 Subject: [PATCH 028/495] Make build tools settings asynchronous. When fetching settings for a build tool, it might require asynchronous actions before it can return (e.g. parsing Gruntfile - which requires spawning a separate Task). --- lib/build.js | 278 ++++++++++++++++++--------------- lib/targets-view.js | 2 +- package.json | 3 +- spec/build-confirm-spec.js | 14 +- spec/build-error-match-spec.js | 18 ++- spec/build-spec.js | 68 +++++--- 6 files changed, 215 insertions(+), 168 deletions(-) diff --git a/lib/build.js b/lib/build.js index c5cee50f..3596312e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -4,6 +4,7 @@ var child_process = require('child_process'); var fs = require('fs'); var path = require('path'); var _ = require('lodash'); +var Promise = require('bluebird'); var XRegExp = require('xregexp').XRegExp; var SaveConfirmView = require('./save-confirm-view'); @@ -12,6 +13,15 @@ var BuildView = require('./build-view'); var GoogleAnalytics = require('./GoogleAnalytics'); var tools = require('./tools'); +function NoToolError(message) { + this.message = message; + this.name = 'NoToolSelected'; + Error.captureStackTrace(this, NoToolError); +} + +NoToolError.prototype = Object.create(Error.prototype); +NoToolError.prototype.constructor = NoToolError; + module.exports = { config: { panelVisibility: { @@ -104,102 +114,107 @@ module.exports = { clearTimeout(this.finishedTimer); }, - refreshTargets: function() { - var path; + activePath: function () { var textEditor = atom.workspace.getActiveTextEditor(); if (!textEditor || !textEditor.getPath()) { /* default to building the first one if no editor is active */ - path = atom.project.getPaths()[0]; + return atom.project.getPaths()[0]; } else { /* otherwise, build the one in the root of the active editor */ - path = _.find(atom.project.getPaths(), function (path) { + return _.find(atom.project.getPaths(), function (path) { var realpath = fs.realpathSync(path); return textEditor.getPath().substr(0, realpath.length) === realpath; }); } + }, - var cmd = { + cmdDefaults: function (path) { + return { env: {}, args: [], cwd: path, sh: true, errorMatch: '' }; + }, - var targets = _.chain(tools) - .filter(function(tool) { - return tool.isEligable(path); - }) - .map(function(tool) { - var settings = tool.settings(path); - if (!settings.targets) { return null; } - return _.map(settings.targets, function(target, name) { - return [name, _.defaults(target, cmd)]; + refreshTargets: function() { + var path = this.activePath(); + + return Promise.resolve(tools) + .bind(this) + .then(function () { + return _.filter(tools, function (tool) { + return tool.isEligable(path); }); }) - .compact() - .flatten(true) - .value(); - - // turn the array of target descriptions into one object. Targets will be - // overwritten by later targets with the same name if present. - targets = _.reduce(targets, function(targets, target) { - targets[target[0]] = target[1]; - return targets; - }, {}); - - if (!_.isNull(this.activeTarget) && _.isUndefined(targets[this.activeTarget])) { - // our active target has been removed, so it is no longer valid - this.activeTarget = null; - } - - this.targets = targets; - return this.targets; + .then(function (tools) { + return Promise.all(_.map(tools, function (tool) { + return tool.settings(path); + })); + }).then(function (settings) { + return _.chain(settings) + .map(function(s) { + if (!s.targets) { + return null; + } + + return _.map(s.targets, function (target, name) { + return [ name, _.defaults(target, this.cmdDefaults(path)) ]; + }.bind(this)); + }.bind(this)) + .compact() + .flatten() + .value(); + }).then(function (targets) { + return _.reduce(targets, function(targets, target) { + targets[target[0]] = target[1]; + return targets; + }, {}); + }).then(function (targets) { + if (!_.isNull(this.activeTarget) && _.isUndefined(targets[this.activeTarget])) { + // our active target has been removed, so it is no longer valid + this.activeTarget = null; + } + return (this.targets = targets); + }); }, selectActiveTarget: function() { - var targets = this.refreshTargets(); - var targetNames = _.keys(targets); - var targetView = new TargetsView(); - targetView.show(targetNames, this.activeTarget, function(newTarget) { - this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; - - var workspaceElement = atom.views.getView(atom.workspace); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + this.refreshTargets().then(function (targets) { + var targetNames = _.keys(targets); + var targetView = new TargetsView(); + targetView.show(targetNames, this.activeTarget, function(newTarget) { + this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; + + var workspaceElement = atom.views.getView(atom.workspace); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }.bind(this)); }.bind(this)); }, buildCommand: function() { - var path; - var textEditor = atom.workspace.getActiveTextEditor(); - if (!textEditor || !textEditor.getPath()) { - /* default to building the first one if no editor is active */ - path = atom.project.getPaths()[0]; - } else { - /* otherwise, build the one in the root of the active editor */ - path = _.find(atom.project.getPaths(), function (path) { - var realpath = fs.realpathSync(path); - return textEditor.getPath().substr(0, realpath.length) === realpath; - }); - } - - var cmd = { - env: {}, - args: [], - cwd: path, - sh: true, - errorMatch: '' - }; - _.find(tools, function (tool) { - if (!tool.isEligable(path)) { - return; - } - GoogleAnalytics.sendEvent('build', 'tool selected', tool.niceName); - cmd = _.defaults(tool.settings(path), cmd); - return true; - }); + var path = this.activePath(); + + return Promise.resolve(tools) + .bind(this) + .then(function (tools) { + return _.find(tools, function (tool) { + if (!tool.isEligable(path)) { + return false; + } + GoogleAnalytics.sendEvent('build', 'tool selected', tool.niceName); + return true; + }); + }).then(function (tool) { + if (!tool) { + throw new NoToolError('No tool fits the current setup.'); + } - return cmd; + return tool.settings(path); + }).then(function (settings) { + return _.defaults(settings, this.cmdDefaults(path)); + }); }, replace: function(value) { @@ -294,68 +309,75 @@ module.exports = { startNewBuild: function() { this.cmd = {}; this.match = []; - try { - this.cmd = this.activeTarget ? this.targets[this.activeTarget] : this.buildCommand(); - } catch (error) { - this.buildView.reset(); - this.buildView.errorMessage('You have a syntax error in your build file.', true); - this.buildView.append(error.message); - return; - } - - GoogleAnalytics.sendEvent('build', 'triggered'); - - if (!this.cmd.exec) { - return; - } - - var env = _.extend(process.env, this.cmd.env); - _.each(env, function(value, key, list) { - list[key] = this.replace(value); - }.bind(this)); - var args = _.map(this.cmd.args, this.replace); - - this.cmd.exec = this.replace(this.cmd.exec); - - this.child = child_process.spawn( - this.cmd.sh ? '/bin/sh' : this.cmd.exec, - this.cmd.sh ? [ '-c', [ this.cmd.exec ].concat(args).join(' ') ] : args, - { cwd: this.replace(this.cmd.cwd), env: env } - ); - - this.stdout = new Buffer(0); - this.child.stdout.on('data', function (buffer) { - this.stdout = Buffer.concat([ this.stdout, buffer ]); - this.buildView.append(buffer); - }.bind(this)); - - this.stderr = new Buffer(0); - this.child.stderr.on('data', function (buffer) { - this.stderr = Buffer.concat([ this.stderr, buffer ]); - this.buildView.append(buffer); - }.bind(this)); - - this.child.on('error', function(err) { - this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec); - this.buildView.append(/\s/.test(this.cmd.exec) ? '`cmd` cannot contain space. Use `args` for arguments.' : ''); - }.bind(this)); + Promise.resolve() + .bind(this) + .then(function () { + return this.activeTarget ? this.targets[this.activeTarget] : this.buildCommand(); + }) + .then(function (cmd) { + this.cmd = cmd; + GoogleAnalytics.sendEvent('build', 'triggered'); - this.child.on('close', function(exitCode) { - this.buildView.buildFinished(0 === exitCode); - if (0 === exitCode) { - GoogleAnalytics.sendEvent('build', 'succeeded'); - this.finishedTimer = setTimeout(function() { - this.buildView.detach(); - }.bind(this), 1000); - } else { - GoogleAnalytics.sendEvent('build', 'failed'); - } - this.child = null; - }.bind(this)); + if (!this.cmd.exec) { + return; + } - this.buildView.buildStarted(); - this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); + var env = _.extend(process.env, this.cmd.env); + _.each(env, function(value, key, list) { + list[key] = this.replace(value); + }.bind(this)); + + var args = _.map(this.cmd.args, this.replace); + + this.cmd.exec = this.replace(this.cmd.exec); + + this.child = child_process.spawn( + this.cmd.sh ? '/bin/sh' : this.cmd.exec, + this.cmd.sh ? [ '-c', [ this.cmd.exec ].concat(args).join(' ') ] : args, + { cwd: this.replace(this.cmd.cwd), env: env } + ); + + this.stdout = new Buffer(0); + this.child.stdout.on('data', function (buffer) { + this.stdout = Buffer.concat([ this.stdout, buffer ]); + this.buildView.append(buffer); + }.bind(this)); + + this.stderr = new Buffer(0); + this.child.stderr.on('data', function (buffer) { + this.stderr = Buffer.concat([ this.stderr, buffer ]); + this.buildView.append(buffer); + }.bind(this)); + + this.child.on('error', function(err) { + this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec); + this.buildView.append(/\s/.test(this.cmd.exec) ? '`cmd` cannot contain space. Use `args` for arguments.' : ''); + }.bind(this)); + + this.child.on('close', function(exitCode) { + this.buildView.buildFinished(0 === exitCode); + if (0 === exitCode) { + GoogleAnalytics.sendEvent('build', 'succeeded'); + this.finishedTimer = setTimeout(function() { + this.buildView.detach(); + }.bind(this), 1000); + } else { + GoogleAnalytics.sendEvent('build', 'failed'); + } + this.child = null; + }.bind(this)); + + this.buildView.buildStarted(); + this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); + }).catch(NoToolError, function (error) { + /* Just ignore this */ + }).catch(function (error) { + this.buildView.reset(); + this.buildView.errorMessage('You have a syntax error in your build file.', true); + this.buildView.append(error.message); + return; + }); }, abort: function(cb) { diff --git a/lib/targets-view.js b/lib/targets-view.js index 42a3ba7b..019a8bf6 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -40,7 +40,7 @@ module.exports = (function() { TargetsView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) { if (itemCount === 0) { - return 'No targets are specified in .atom-build.json'; + return 'No targets founds.'; } else { return 'No matches'; } diff --git a/package.json b/package.json index 5d8b7e09..0a0ce091 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "atom": ">=0.50.0" }, "dependencies": { - "lodash": "^2.4.1", + "lodash": "^3.8.0", + "bluebird": "^2.9.25", "ansi-to-html": "^0.3.0", "temp": "^0.8.1", "fs-plus": "^2.4.0", diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index f0f2a0de..61478e81 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -41,28 +41,23 @@ describe('Build', function() { it('should show the save confirmation', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - // console.log('writing makefile'); fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); waitsForPromise(function() { - // console.log('testing if makefile is open'); return atom.workspace.open('Makefile'); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - // console.log('adding text'); editor.insertText('hello kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); waitsFor(function() { - // console.log('checking for focused element'); return workspaceElement.querySelector(':focus'); }); runs(function() { - // console.log('verifying that success is the focuesed element'); expect(workspaceElement.querySelector('.btn-success:focus')).toExist(); }); }); @@ -114,7 +109,8 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -147,7 +143,8 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -182,7 +179,8 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index ee17cef4..e4426a7d 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -48,7 +48,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -75,7 +76,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -98,7 +100,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -122,7 +125,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -183,7 +187,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -246,7 +251,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { diff --git a/spec/build-spec.js b/spec/build-spec.js index d0f5d210..e179ed3c 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -150,7 +150,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -166,7 +167,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -191,7 +193,8 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -212,7 +215,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -230,7 +234,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -250,7 +255,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }, 'build to be successful', 10000); runs(function() { @@ -281,7 +287,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -297,7 +304,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -313,7 +321,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -329,7 +338,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -345,7 +355,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -361,7 +372,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('error'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); }); runs(function() { @@ -380,7 +392,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -399,7 +412,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -416,7 +430,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -433,7 +448,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -453,7 +469,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }, 'build to be successful', 10000); runs(function() { @@ -473,7 +490,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -499,7 +517,8 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -523,7 +542,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -549,8 +569,8 @@ describe('Build', function() { }); waitsFor(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { @@ -596,8 +616,8 @@ describe('Build', function() { }); waitsFor(function() { - expect(workspaceElement.querySelector('.build ')).toExist(); - return workspaceElement.querySelector('.build .title').classList.contains('success'); + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); }); runs(function() { From e0bc4375dfccb1467bf40a19d614394496911173 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 18 May 2015 23:00:57 +0200 Subject: [PATCH 029/495] Build tools: Grunt now parses targets --- lib/tools/Grunt.js | 32 +++++++++++++++++++++++++++++--- lib/tools/atom-build.js | 3 +-- lib/tools/grunt-parser-task.js | 25 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 lib/tools/grunt-parser-task.js diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index a2feab62..b82b8434 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -1,6 +1,11 @@ 'use strict'; var fs = require('fs'); +var _ = require('lodash'); +var Task = require('atom').Task; +var Promise = require('bluebird'); + +var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'Grunt'; @@ -8,9 +13,30 @@ module.exports.isEligable = function (path) { return fs.existsSync(path + '/Gruntfile.js'); }; -module.exports.settings = function (path) { +module.exports.createConfig = function(path, args) { + var exec = fs.existsSync(path + '/node_modules/.bin/grunt') ? path + '/node_modules/.bin/grunt' : 'grunt'; return { - exec: fs.existsSync(path + '/node_modules/.bin/grunt') ? path + '/node_modules/.bin/grunt' : 'grunt', - sh: false + exec: exec, + sh: false, + args: args }; }; + +module.exports.settings = function (path) { + return new Promise(function(resolve, reject) { + process.env.NODE_PATH = path + '/node_modules:' + originalNodePath; + Task.once(require.resolve('./grunt-parser-task.js'), path, function (result) { + + var config = this.createConfig(path); + if (result.tasks) { + config.targets = _.zipObject(_.map(result.tasks, function(task) { + return [ 'Grunt: ' + task, this.createConfig(path, [ task ]) ]; + }.bind(this))); + } + + return resolve(config); + }.bind(this)); + }.bind(this)).finally(function () { + process.env.NODE_PATH = originalNodePath; + }); +}; diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index f443ccea..66e20040 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -24,13 +24,12 @@ module.exports.settings = function (path) { }; }; - var build = require(realAtomBuild); var config = createBuildConfig(build); if (build.targets) { config.targets = _.object(_.map(build.targets, function(target, name) { - return [name, createBuildConfig(target)]; + return [ 'Custom: ' + name, createBuildConfig(target) ]; })); } diff --git a/lib/tools/grunt-parser-task.js b/lib/tools/grunt-parser-task.js new file mode 100644 index 00000000..6b5e628b --- /dev/null +++ b/lib/tools/grunt-parser-task.js @@ -0,0 +1,25 @@ +'use strict'; + +/** + * This has to be done in a separate task since Grunt depends + * on stuff that does unsafe evals. We don't want, and are not + * allowed to do this in the context of the Atom application. + */ + +try { + var grunt = require('grunt'); +} catch (e) {} + +module.exports = function (path) { + try { + if (!grunt) { + throw new Error('Grunt is not installed.'); + } + + process.chdir(path); + require(path + '/Gruntfile.js')(grunt); + return { tasks: Object.keys(grunt.task._tasks) }; + } catch (e) { + return { error: e }; + } +}; From e076b58f354c6658378e677b20ca03c66bc5be4a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 21 May 2015 12:49:11 +0200 Subject: [PATCH 030/495] Build tools: Gulp now parses targets --- lib/tools/Grunt.js | 22 +++++++++++-------- lib/tools/grunt-parser-task.js | 7 ++++++ lib/tools/gulp-parser-task.js | 32 +++++++++++++++++++++++++++ lib/tools/gulp.js | 40 +++++++++++++++++++++++++++++----- 4 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 lib/tools/gulp-parser-task.js diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index b82b8434..292bd505 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -1,6 +1,8 @@ 'use strict'; var fs = require('fs'); +var path = require('path'); +var util = require('util'); var _ = require('lodash'); var Task = require('atom').Task; var Promise = require('bluebird'); @@ -9,12 +11,12 @@ var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'Grunt'; -module.exports.isEligable = function (path) { - return fs.existsSync(path + '/Gruntfile.js'); +module.exports.isEligable = function (cwd) { + return fs.existsSync(cwd + '/Gruntfile.js'); }; -module.exports.createConfig = function(path, args) { - var exec = fs.existsSync(path + '/node_modules/.bin/grunt') ? path + '/node_modules/.bin/grunt' : 'grunt'; +module.exports.createConfig = function(cwd, args) { + var exec = fs.existsSync(cwd + '/node_modules/.bin/grunt') ? cwd + '/node_modules/.bin/grunt' : 'grunt'; return { exec: exec, sh: false, @@ -22,15 +24,17 @@ module.exports.createConfig = function(path, args) { }; }; -module.exports.settings = function (path) { +module.exports.settings = function (cwd) { return new Promise(function(resolve, reject) { - process.env.NODE_PATH = path + '/node_modules:' + originalNodePath; - Task.once(require.resolve('./grunt-parser-task.js'), path, function (result) { + /* This is set so that the spawned Task gets its own instance of grunt */ + process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); - var config = this.createConfig(path); + Task.once(require.resolve('./grunt-parser-task.js'), cwd, function (result) { + + var config = this.createConfig(cwd); if (result.tasks) { config.targets = _.zipObject(_.map(result.tasks, function(task) { - return [ 'Grunt: ' + task, this.createConfig(path, [ task ]) ]; + return [ 'Grunt: ' + task, this.createConfig(cwd, [ task ]) ]; }.bind(this))); } diff --git a/lib/tools/grunt-parser-task.js b/lib/tools/grunt-parser-task.js index 6b5e628b..cae337b8 100644 --- a/lib/tools/grunt-parser-task.js +++ b/lib/tools/grunt-parser-task.js @@ -17,6 +17,13 @@ module.exports = function (path) { } process.chdir(path); + + /* jshint -W020 */ + /* When spawning this, we are not a browser anymore. Disable these */ + navigator = undefined; + window = undefined; + /* jshint +W020 */ + require(path + '/Gruntfile.js')(grunt); return { tasks: Object.keys(grunt.task._tasks) }; } catch (e) { diff --git a/lib/tools/gulp-parser-task.js b/lib/tools/gulp-parser-task.js new file mode 100644 index 00000000..b0468cf6 --- /dev/null +++ b/lib/tools/gulp-parser-task.js @@ -0,0 +1,32 @@ +'use strict'; + +/** + * This has to be done in a separate task since gulp depends + * on stuff that does unsafe evals. We don't want, and are not + * allowed to do this in the context of the Atom application. + */ + +try { + var gulp = require('gulp'); +} catch (e) {} + +module.exports = function (path) { + try { + if (!gulp) { + throw new Error('Gulp is not installed.'); + } + + process.chdir(path); + + /* jshint -W020 */ + /* When spawning this, we are not a browser anymore. Disable these */ + navigator = undefined; + window = undefined; + /* jshint +W020 */ + + require(path + '/gulpfile.js'); + return { tasks: Object.keys(gulp.tasks) }; + } catch (e) { + return { error: e }; + } +}; diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 1e61cc49..1b3a7faa 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -1,16 +1,46 @@ 'use strict'; var fs = require('fs'); +var path = require('path'); +var util = require('util'); +var _ = require('lodash'); +var Task = require('atom').Task; +var Promise = require('bluebird'); + +var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'gulp'; -module.exports.isEligable = function (path) { - return fs.existsSync(path + '/gulpfile.js'); +module.exports.isEligable = function (cwd) { + return fs.existsSync(cwd + '/gulpfile.js'); }; -module.exports.settings = function (path) { +module.exports.createConfig = function (cwd, args) { + var exec = fs.existsSync(cwd + '/node_modules/.bin/gulp') ? cwd + '/node_modules/.bin/gulp' : 'gulp'; return { - exec: fs.existsSync(path + '/node_modules/.bin/gulp') ? path + '/node_modules/.bin/gulp' : 'gulp', - sh: false + exec: exec, + sh: false, + args: args }; }; + +module.exports.settings = function (cwd) { + return new Promise(function(resolve, reject) { + /* This is set so that the spawned Task gets its own instance of gulp */ + process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); + + Task.once(require.resolve('./gulp-parser-task.js'), cwd, function (result) { + + var config = this.createConfig(cwd); + if (result.tasks) { + config.targets = _.zipObject(_.map(result.tasks, function(task) { + return [ 'Gulp: ' + task, this.createConfig(cwd, [ task ]) ]; + }.bind(this))); + } + + return resolve(config); + }.bind(this)); + }.bind(this)).finally(function () { + process.env.NODE_PATH = originalNodePath; + }); +}; From fbc6a06d094906a8664680cedb75ebc077b6d350 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 21 May 2015 12:53:09 +0200 Subject: [PATCH 031/495] Prepare 0.34.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5d8b7e09..16fda8ed 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.33.0", + "version": "0.34.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 6b044b2cabe3bf8105073ffc87182dce9da155d0 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 21 May 2015 15:43:43 +0200 Subject: [PATCH 032/495] TargetsView: show panel and loading message Also scrolls the list so the active target is visible and selected. --- lib/build.js | 22 ++++++++++++---------- lib/targets-view.js | 37 ++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/build.js b/lib/build.js index 3596312e..0b317573 100644 --- a/lib/build.js +++ b/lib/build.js @@ -181,16 +181,18 @@ module.exports = { }, selectActiveTarget: function() { - this.refreshTargets().then(function (targets) { - var targetNames = _.keys(targets); - var targetView = new TargetsView(); - targetView.show(targetNames, this.activeTarget, function(newTarget) { - this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; - - var workspaceElement = atom.views.getView(atom.workspace); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }.bind(this)); - }.bind(this)); + var targetsView = new TargetsView(this.activeTarget); + targetsView.setLoading('Loading project build targets...\u2026'); + + this.refreshTargets().bind(this).then(function (targets) { + targetsView.setItems(_.keys(targets)); + return targetsView.awaitSelection(); + }).then(function(newTarget) { + this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; + + var workspaceElement = atom.views.getView(atom.workspace); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); }, buildCommand: function() { diff --git a/lib/targets-view.js b/lib/targets-view.js index 019a8bf6..e6d97628 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -2,10 +2,13 @@ var SelectListView = require('atom-space-pen-views').SelectListView; var cscompatability = require('./cscompatability'); +var Promise = require('bluebird'); module.exports = (function() { - function TargetsView() { + function TargetsView(activeTarget) { SelectListView.apply(this, arguments); + this.activeTarget = activeTarget; + this.show(); } cscompatability.extends(TargetsView, SelectListView); @@ -15,14 +18,11 @@ module.exports = (function() { this.list.addClass('mark-active'); }; - TargetsView.prototype.show = function(targets, activeTarget, cb) { + TargetsView.prototype.show = function() { this.panel = atom.workspace.addModalPanel({ item: this }); - this.activeTarget = activeTarget; - this.callback = cb; this.panel.show(); - this.setItems(targets); this.focusFilterEditor(); }; @@ -30,6 +30,16 @@ module.exports = (function() { this.panel.hide(); }; + TargetsView.prototype.setItems = function () { + TargetsView.__super__.setItems.apply(this, arguments); + + var activeItemView = this.find('.active'); + if (0 < activeItemView.length) { + this.selectItemView(activeItemView); + this.scrollToItemView(activeItemView); + } + }; + TargetsView.prototype.viewForItem = function(targetName) { var activeTarget = this.activeTarget; return TargetsView.render(function() { @@ -39,15 +49,20 @@ module.exports = (function() { }; TargetsView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) { - if (itemCount === 0) { - return 'No targets founds.'; - } else { - return 'No matches'; - } + return (0 === itemCount) ? 'No targets found.' : 'No matches'; + }; + + TargetsView.prototype.awaitSelection = function () { + return new Promise(function (resolve, reject) { + this.resolveFunction = resolve; + }.bind(this)); }; TargetsView.prototype.confirmed = function(target) { - this.callback(target); + if (this.resolveFunction) { + this.resolveFunction(target); + this.resolveFunction = null; + } this.hide(); }; From 547231fe7a219d8dec66d5d156d91afecdb5b834 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 21 May 2015 18:03:54 +0200 Subject: [PATCH 033/495] Build targets: Everything is a target Each tool should now return an array of build targets. Event if it provides just one target. Each build config can now include a name which is used when displaying the target in the targets-view. --- lib/build-view.js | 8 ++-- lib/build.js | 90 +++++++++++++---------------------------- lib/targets-view.js | 7 +++- lib/tools/Cargo.js | 5 ++- lib/tools/Elixir.js | 5 ++- lib/tools/Grunt.js | 24 +++++++---- lib/tools/atom-build.js | 14 +++---- lib/tools/gulp.js | 31 +++++++------- lib/tools/make.js | 5 ++- lib/tools/npm_apm.js | 1 + 10 files changed, 86 insertions(+), 104 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 7aa57268..de339d7a 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -174,11 +174,11 @@ module.exports = (function() { this.title.text('Aborted!'); }; - BuildView.prototype.errorMessage = function(title, error) { + BuildView.prototype.errorMessage = function(title, message) { + this.reset(); + this.title.addClass('error'); this.title.text(title); - if (error) { - this.title.addClass('error'); - } + this.append(message); this.attach(); }; diff --git a/lib/build.js b/lib/build.js index 0b317573..c8827a02 100644 --- a/lib/build.js +++ b/lib/build.js @@ -81,6 +81,7 @@ module.exports = { this.stdout = new Buffer(0); this.stderr = new Buffer(0); atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this)); + atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); atom.commands.add('atom-workspace', 'build:error-match', this.errorMatch.bind(this)); atom.commands.add('atom-workspace', 'build:error-match-first', this.errorMatchFirst.bind(this)); atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this)); @@ -92,7 +93,6 @@ module.exports = { GoogleAnalytics.sendEvent('build', 'not confirmed'); this.saveConfirmView.cancel(); }.bind(this)); - atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); atom.workspace.observeTextEditors(function(editor) { editor.onDidSave(function(event) { @@ -140,6 +140,7 @@ module.exports = { refreshTargets: function() { var path = this.activePath(); + var prioritizedTarget; return Promise.resolve(tools) .bind(this) @@ -152,73 +153,46 @@ module.exports = { return Promise.all(_.map(tools, function (tool) { return tool.settings(path); })); - }).then(function (settings) { - return _.chain(settings) - .map(function(s) { - if (!s.targets) { - return null; - } - - return _.map(s.targets, function (target, name) { - return [ name, _.defaults(target, this.cmdDefaults(path)) ]; - }.bind(this)); - }.bind(this)) - .compact() - .flatten() - .value(); - }).then(function (targets) { - return _.reduce(targets, function(targets, target) { - targets[target[0]] = target[1]; - return targets; - }, {}); - }).then(function (targets) { - if (!_.isNull(this.activeTarget) && _.isUndefined(targets[this.activeTarget])) { - // our active target has been removed, so it is no longer valid - this.activeTarget = null; + }) + .then(_.flatten) + .then(function (settings) { + if (0 === _.size(settings)) { + throw new NoToolError(); + } + + prioritizedTarget = settings[0].name; + return _.map(settings, function (s) { + return [ s.name, _.defaults(s, this.cmdDefaults(path)) ]; + }.bind(this)); + }) + .then(_.zipObject) + .then(function (targets) { + if (_.isNull(this.activeTarget) || _.isUndefined(targets[this.activeTarget])) { + /* Active target has been removed or not set. Set it to the highest prio target */ + this.activeTarget = prioritizedTarget; } return (this.targets = targets); + }).catch(function (error) { + this.buildView.errorMessage('You have a syntax error in your build file.', error.message); }); }, selectActiveTarget: function() { - var targetsView = new TargetsView(this.activeTarget); + var targetsView = new TargetsView(); targetsView.setLoading('Loading project build targets...\u2026'); this.refreshTargets().bind(this).then(function (targets) { + targetsView.setActiveTarget(this.activeTarget); targetsView.setItems(_.keys(targets)); return targetsView.awaitSelection(); }).then(function(newTarget) { - this.activeTarget = (newTarget === this.activeTarget) ? null : newTarget; + this.activeTarget = newTarget; var workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); }, - buildCommand: function() { - var path = this.activePath(); - - return Promise.resolve(tools) - .bind(this) - .then(function (tools) { - return _.find(tools, function (tool) { - if (!tool.isEligable(path)) { - return false; - } - GoogleAnalytics.sendEvent('build', 'tool selected', tool.niceName); - return true; - }); - }).then(function (tool) { - if (!tool) { - throw new NoToolError('No tool fits the current setup.'); - } - - return tool.settings(path); - }).then(function (settings) { - return _.defaults(settings, this.cmdDefaults(path)); - }); - }, - replace: function(value) { var editor = atom.workspace.getActiveTextEditor(); if (editor && 'untitled' !== editor.getTitle()) { @@ -264,9 +238,7 @@ module.exports = { fs.exists(file, function (exists) { if (!exists) { - this.buildView.reset(); - this.buildView.errorMessage('Error matching failed:', true); - this.buildView.append('Matched file does not exist: ' + file); + this.buildView.errorMessage('Error matching failed:', 'Matched file does not exist: ' + file); return; } @@ -315,13 +287,14 @@ module.exports = { Promise.resolve() .bind(this) .then(function () { - return this.activeTarget ? this.targets[this.activeTarget] : this.buildCommand(); + return (this.activeTarget) ? this.targets : this.refreshTargets(); }) - .then(function (cmd) { - this.cmd = cmd; + .then(function (targets) { + this.cmd = targets[this.activeTarget]; GoogleAnalytics.sendEvent('build', 'triggered'); if (!this.cmd.exec) { + this.buildView.errorMessage('Invalid build file.', 'No executable command specified.'); return; } @@ -374,11 +347,6 @@ module.exports = { this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); }).catch(NoToolError, function (error) { /* Just ignore this */ - }).catch(function (error) { - this.buildView.reset(); - this.buildView.errorMessage('You have a syntax error in your build file.', true); - this.buildView.append(error.message); - return; }); }, diff --git a/lib/targets-view.js b/lib/targets-view.js index e6d97628..49063c6a 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -5,9 +5,8 @@ var cscompatability = require('./cscompatability'); var Promise = require('bluebird'); module.exports = (function() { - function TargetsView(activeTarget) { + function TargetsView() { SelectListView.apply(this, arguments); - this.activeTarget = activeTarget; this.show(); } @@ -40,6 +39,10 @@ module.exports = (function() { } }; + TargetsView.prototype.setActiveTarget = function (target) { + this.activeTarget = target; + }; + TargetsView.prototype.viewForItem = function(targetName) { var activeTarget = this.activeTarget; return TargetsView.render(function() { diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js index a136769f..1c696eda 100644 --- a/lib/tools/Cargo.js +++ b/lib/tools/Cargo.js @@ -9,10 +9,11 @@ module.exports.isEligable = function (path) { }; module.exports.settings = function (path) { - return { + return [ { + name: 'Cargo: default', exec: 'cargo', args: [ 'build' ], sh: false, errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' - }; + } ]; }; diff --git a/lib/tools/Elixir.js b/lib/tools/Elixir.js index a30b2ac2..1e26e864 100644 --- a/lib/tools/Elixir.js +++ b/lib/tools/Elixir.js @@ -9,9 +9,10 @@ module.exports.isEligable = function (path) { }; module.exports.settings = function (path) { - return { + return [ { + name: 'Elixir: default', exec: 'mix', args: [ 'compile' ], sh: false - }; + } ]; }; diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 292bd505..6de85920 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -25,22 +25,30 @@ module.exports.createConfig = function(cwd, args) { }; module.exports.settings = function (cwd) { + var createConfig = function (name, args) { + var exec = fs.existsSync(cwd + '/node_modules/.bin/grunt') ? cwd + '/node_modules/.bin/grunt' : 'grunt'; + return { + name: name, + exec: exec, + sh: false, + args: args + }; + }; + return new Promise(function(resolve, reject) { /* This is set so that the spawned Task gets its own instance of grunt */ process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); Task.once(require.resolve('./grunt-parser-task.js'), cwd, function (result) { - var config = this.createConfig(cwd); - if (result.tasks) { - config.targets = _.zipObject(_.map(result.tasks, function(task) { - return [ 'Grunt: ' + task, this.createConfig(cwd, [ task ]) ]; - }.bind(this))); - } + var config = []; + _.forEach(result.tasks || [], function (task) { + config.push(createConfig('Grunt: ' + task, [ task ])); + }); return resolve(config); - }.bind(this)); - }.bind(this)).finally(function () { + }); + }).finally(function () { process.env.NODE_PATH = originalNodePath; }); }; diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index 66e20040..e3b522e9 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -13,8 +13,9 @@ module.exports.settings = function (path) { var realAtomBuild = fs.realpathSync(path + '/.atom-build.json'); delete require.cache[realAtomBuild]; - var createBuildConfig = function(build) { + var createBuildConfig = function(build, name) { return { + name: 'Custom: ' + name, exec: build.cmd, env: build.env, args: build.args, @@ -25,13 +26,12 @@ module.exports.settings = function (path) { }; var build = require(realAtomBuild); - var config = createBuildConfig(build); + var config = []; - if (build.targets) { - config.targets = _.object(_.map(build.targets, function(target, name) { - return [ 'Custom: ' + name, createBuildConfig(target) ]; - })); - } + config.push(createBuildConfig(build, build.name || 'default')); + _.forEach(build.targets || [], function (target, name) { + config.push(createBuildConfig(target, name)); + }); return config; }; diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 1b3a7faa..d8c349b1 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -15,32 +15,31 @@ module.exports.isEligable = function (cwd) { return fs.existsSync(cwd + '/gulpfile.js'); }; -module.exports.createConfig = function (cwd, args) { - var exec = fs.existsSync(cwd + '/node_modules/.bin/gulp') ? cwd + '/node_modules/.bin/gulp' : 'gulp'; - return { - exec: exec, - sh: false, - args: args +module.exports.settings = function (cwd) { + var createConfig = function (name, args) { + var exec = fs.existsSync(cwd + '/node_modules/.bin/gulp') ? cwd + '/node_modules/.bin/gulp' : 'gulp'; + return { + name: name, + exec: exec, + sh: false, + args: args + }; }; -}; -module.exports.settings = function (cwd) { return new Promise(function(resolve, reject) { /* This is set so that the spawned Task gets its own instance of gulp */ process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); Task.once(require.resolve('./gulp-parser-task.js'), cwd, function (result) { - var config = this.createConfig(cwd); - if (result.tasks) { - config.targets = _.zipObject(_.map(result.tasks, function(task) { - return [ 'Gulp: ' + task, this.createConfig(cwd, [ task ]) ]; - }.bind(this))); - } + var config = []; + _.forEach(result.tasks || [], function (task) { + config.push(createConfig('Gulp: ' + task, [ task ])); + }); return resolve(config); - }.bind(this)); - }.bind(this)).finally(function () { + }); + }).finally(function () { process.env.NODE_PATH = originalNodePath; }); }; diff --git a/lib/tools/make.js b/lib/tools/make.js index 89c2ca00..2e558183 100644 --- a/lib/tools/make.js +++ b/lib/tools/make.js @@ -9,8 +9,9 @@ module.exports.isEligable = function (path) { }; module.exports.settings = function (path) { - return { + return [ { + name: 'default', exec: 'make', sh: false - }; + } ]; }; diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index 52047578..0bf3f072 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -25,6 +25,7 @@ module.exports.settings = function (path) { var pkg = require(realPackage); return { + name: pkg.engines.node ? 'npm' : 'apm', exec: pkg.engines.node ? 'npm' : 'apm', args: [ '--color=always', 'install' ], sh: false From 814cef817725e591d08b2a1e4dacfdc631c02896 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 21 May 2015 18:45:21 +0200 Subject: [PATCH 034/495] Build: Better error management --- lib/build.js | 16 +++++++++++----- lib/tools/make.js | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/build.js b/lib/build.js index c8827a02..cec50b8f 100644 --- a/lib/build.js +++ b/lib/build.js @@ -13,8 +13,8 @@ var BuildView = require('./build-view'); var GoogleAnalytics = require('./GoogleAnalytics'); var tools = require('./tools'); -function NoToolError(message) { - this.message = message; +function NoToolError() { + this.message = 'No tool can provide any build configurations.'; this.name = 'NoToolSelected'; Error.captureStackTrace(this, NoToolError); } @@ -172,8 +172,6 @@ module.exports = { this.activeTarget = prioritizedTarget; } return (this.targets = targets); - }).catch(function (error) { - this.buildView.errorMessage('You have a syntax error in your build file.', error.message); }); }, @@ -190,6 +188,10 @@ module.exports = { var workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); + }).catch(NoToolError, function (error) { + targetsView.setError(error.message); + }).catch(function (error) { + targetsView.setError('Something went wrong: ' + error.message); }); }, @@ -346,7 +348,11 @@ module.exports = { this.buildView.buildStarted(); this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); }).catch(NoToolError, function (error) { - /* Just ignore this */ + /* Maybe we should show the build-panel with an error message here? */ + }).catch(SyntaxError, function (error) { + this.buildView.errorMessage('You have a syntax error in your build file.', error.message); + }).catch(function (error) { + this.buildView.errorMessage('Ooops. Something went wrong.', error.message); }); }, diff --git a/lib/tools/make.js b/lib/tools/make.js index 2e558183..ee2928ed 100644 --- a/lib/tools/make.js +++ b/lib/tools/make.js @@ -10,7 +10,7 @@ module.exports.isEligable = function (path) { module.exports.settings = function (path) { return [ { - name: 'default', + name: 'GNU Make: default', exec: 'make', sh: false } ]; From 683ebb12b26475de82edf42d067afefb5d8930f3 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 22 May 2015 16:19:03 +0200 Subject: [PATCH 035/495] Spec: Initial spec for build targets Verifies basic functionality as well as the generated targets from `.atom-build.json`, `Gruntfile.js` and `gulpfile.js`. --- lib/targets-view.js | 2 +- package.json | 1 + spec/build-targets-spec.js | 240 ++++++++++++++++++++++++++ spec/fixture/.atom-build.targets.json | 9 + spec/fixture/Gruntfile.js | 10 ++ spec/fixture/gulpfile.js | 10 ++ spec/spec-helpers.js | 37 ++++ 7 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 spec/build-targets-spec.js create mode 100644 spec/fixture/.atom-build.targets.json create mode 100644 spec/spec-helpers.js diff --git a/lib/targets-view.js b/lib/targets-view.js index 49063c6a..43308cf6 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -47,7 +47,7 @@ module.exports = (function() { var activeTarget = this.activeTarget; return TargetsView.render(function() { var activeClass = (targetName === activeTarget ? 'active' : ''); - this.li({ class: activeClass }, targetName); + this.li({ class: activeClass + ' build-target' }, targetName); }); }; diff --git a/package.json b/package.json index 983f5064..c8586ecb 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "ansi-to-html": "^0.3.0", "temp": "^0.8.1", "fs-plus": "^2.4.0", + "fs-extra": "^0.18.3", "atom-space-pen-views": "^2.0.3", "xregexp": "^2.0.0", "node-uuid": "^1.4.3", diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js new file mode 100644 index 00000000..ec3d3532 --- /dev/null +++ b/spec/build-targets-spec.js @@ -0,0 +1,240 @@ +var _ = require('lodash'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs-extra')); +var temp = Promise.promisifyAll(require('temp')); +var specHelpers = require('./spec-helpers'); + +describe('Build', function() { + 'use strict'; + + var directory = null; + var workspaceElement = null; + + temp.track(); + + beforeEach(function() { + workspaceElement = atom.views.getView(atom.workspace); + + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + jasmine.attachToDOM(workspaceElement); + + waitsForPromise(function() { + return temp.mkdirAsync({ prefix: 'atom-build-spec-' }).then(function (dir) { + return fs.realpathAsync(dir); + }).then(function (dir) { + directory = dir + '/'; + atom.project.setPaths([ directory ]); + return atom.packages.activatePackage('build'); + }); + }); + }); + + afterEach(function() { + return fs.removeAsync(directory); + }); + + describe('when multiple targets exists', function () { + + it('should list those targets in a SelectListView (from .atom-build.json)', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/.atom-build.targets.json'; + return fs.copyAsync(file, directory + '/.atom-build.json'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'Custom: The default build', 'Custom: Some customized build' ]); + }); + }); + + it('should list those targets in a SelectListView (from Gruntfile.js)', function () { + waitsForPromise(function () { + return Promise.resolve() + .then(function () { + return fs.copyAsync(__dirname + '/fixture/Gruntfile.js', directory + '/Gruntfile.js'); + }) + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGrunt(directory)); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'Grunt: default', 'Grunt: other task', 'Grunt: dev task' ]); + }); + }); + + it('should list those targets in a SelectListView (from gulpfile.js)', function () { + waitsForPromise(function () { + return Promise.resolve() + .then(function () { + return fs.copyAsync(__dirname + '/fixture/gulpfile.js', directory + '/gulpfile.js'); + }) + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGulp(directory)); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'Gulp: default', 'Gulp: dev build', 'Gulp: watch' ]); + }); + }); + + it('should mark the first target as active', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/.atom-build.targets.json'; + return fs.copyAsync(file, directory + '/.atom-build.json'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var el = workspaceElement.querySelector('.select-list li.build-target'); // querySelector selects the first element + expect(el).toHaveClass('selected'); + expect(el).toHaveClass('active'); + }); + }); + + it('it should run the selected build', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/.atom-build.targets.json'; + return fs.copyAsync(file, directory + '/.atom-build.json'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + }); + }); + + it('it should run the default target if no selection has been made', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/.atom-build.targets.json'; + return fs.copyAsync(file, directory + '/.atom-build.json'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + }); + }); + + it('run the selected target if selection has changed, and subsequent build should run that target', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/.atom-build.targets.json'; + return fs.copyAsync(file, directory + '/.atom-build.json'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:move-down'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.selected').textContent === 'Custom: Some customized build'; + }); + + runs(function () { + atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/customized/); + atom.commands.dispatch(workspaceElement.querySelector('.build'), 'build:stop'); + }); + + waitsFor(function () { + return !workspaceElement.querySelector('.build'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/customized/); + }); + }); + }); +}); diff --git a/spec/fixture/.atom-build.targets.json b/spec/fixture/.atom-build.targets.json new file mode 100644 index 00000000..25250ece --- /dev/null +++ b/spec/fixture/.atom-build.targets.json @@ -0,0 +1,9 @@ +{ + "name": "The default build", + "cmd": "echo default", + "targets": { + "Some customized build": { + "cmd": "echo customized" + } + } +} diff --git a/spec/fixture/Gruntfile.js b/spec/fixture/Gruntfile.js index b512db48..ade8cad5 100644 --- a/spec/fixture/Gruntfile.js +++ b/spec/fixture/Gruntfile.js @@ -1,6 +1,16 @@ module.exports = function(grunt) { + 'use strict'; + grunt.initConfig({}); grunt.registerTask('default', function() { console.log('Surprising is the passing of time. But not so, as the time of passing'); }); + + grunt.registerTask('other task', function () { + console.log('doing heavy machinery stuff'); + }); + + grunt.registerTask('dev task', function () { + console.log('doing dev build'); + }); }; diff --git a/spec/fixture/gulpfile.js b/spec/fixture/gulpfile.js index 6e8717ac..76c6410f 100644 --- a/spec/fixture/gulpfile.js +++ b/spec/fixture/gulpfile.js @@ -1,5 +1,15 @@ +'use strict'; + var gulp = require('gulp'); gulp.task('default', function() { console.log('gulp built'); }); + +gulp.task('dev build', function () { + console.log('dev build'); +}); + +gulp.task('watch', function () { + console.log('watch'); +}); diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js new file mode 100644 index 00000000..30564ef5 --- /dev/null +++ b/spec/spec-helpers.js @@ -0,0 +1,37 @@ +'use strict'; + +var path = require('path'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs-extra')); + +module.exports = { + setupNodeModules: function (directory) { + return function () { + return fs.copyAsync(path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules')); + }; + }, + + setupGrunt: function (directory) { + var binGrunt = path.join(directory, 'node_modules', '.bin', 'grunt'); + var realGrunt = path.join(directory, 'node_modules', 'grunt-cli', 'bin', 'grunt'); + return function () { + return Promise.all([ + fs.unlinkAsync(binGrunt), + fs.chmodAsync(realGrunt, parseInt('0700', 8)), + fs.symlinkAsync(realGrunt, binGrunt) + ]); + }; + }, + + setupGulp: function (directory) { + var binGulp = path.join(directory, 'node_modules', '.bin', 'gulp'); + var realGulp = path.join(directory, 'node_modules', 'gulp', 'bin', 'gulp.js'); + return function () { + return Promise.all([ + fs.unlinkAsync(binGulp), + fs.chmodAsync(realGulp, parseInt('0700', 8)), + fs.symlinkAsync(realGulp, binGulp) + ]); + }; + } +}; From d8549468e744f4c392143f299b2726eefeb98e42 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 22 May 2015 16:44:06 +0200 Subject: [PATCH 036/495] Specs: Use common helpers Also does the setup a little more async --- spec/build-spec.js | 59 +++++++++++++++++--------------------- spec/build-targets-spec.js | 2 +- spec/spec-helpers.js | 10 ++++--- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/spec/build-spec.js b/spec/build-spec.js index e179ed3c..2292d874 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,6 +1,7 @@ -var fs = require('fs-plus'); -var path = require('path'); -var temp = require('temp'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs-extra')); +var temp = Promise.promisifyAll(require('temp')); +var specHelpers = require('./spec-helpers'); describe('Build', function() { 'use strict'; @@ -28,45 +29,35 @@ describe('Build', function() { temp.track(); beforeEach(function() { - directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; - atom.project.setPaths([ directory ]); - atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); - // Set up dependencies - fs.copySync(path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules')); - - // Set up grunt - var binGrunt = path.join(directory, 'node_modules', '.bin', 'grunt'); - var realGrunt = path.join(directory, 'node_modules', 'grunt-cli', 'bin', 'grunt'); - fs.unlinkSync(binGrunt); - fs.chmodSync(realGrunt, parseInt('0700', 8)); - fs.symlinkSync(realGrunt, binGrunt); - - // Set up gulp - var binGulp = path.join(directory, 'node_modules', '.bin', 'gulp'); - var realGulp = path.join(directory, 'node_modules', 'gulp', 'bin', 'gulp.js'); - fs.unlinkSync(binGulp); - fs.chmodSync(realGulp, parseInt('0700', 8)); - fs.symlinkSync(realGulp, binGulp); - + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - runs(function() { - workspaceElement = atom.views.getView(atom.workspace); - jasmine.attachToDOM(workspaceElement); - }); - waitsForPromise(function() { - return atom.packages.activatePackage('build'); + return temp.mkdirAsync({ prefix: 'atom-build-spec-' }).then(function (dir) { + return fs.realpathAsync(dir); + }).then(function (dir) { + directory = dir + '/'; + atom.project.setPaths([ directory ]); + return specHelpers.setupNodeModules(directory)(); + }).then(function () { + return Promise.all([ + specHelpers.setupGrunt(directory)(), + specHelpers.setupGulp(directory)() + ]); + }).then(function () { + return atom.packages.activatePackage('build'); + }); }); }); afterEach(function() { - fs.removeSync(directory); + fs.removeAsync(directory); }); describe('when panel visibility is set to show on error', function() { @@ -122,9 +113,8 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { - return workspaceElement.querySelector('.build .title').classList.contains('success'); - }); + /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ + waits(200); runs(function() { expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1); @@ -138,6 +128,9 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); + /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ + waits(200); + runs(function() { expect(workspaceElement.querySelector('.build')).not.toExist(); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index ec3d3532..ded596a0 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -35,7 +35,7 @@ describe('Build', function() { }); afterEach(function() { - return fs.removeAsync(directory); + fs.removeAsync(directory); }); describe('when multiple targets exists', function () { diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js index 30564ef5..c7301292 100644 --- a/spec/spec-helpers.js +++ b/spec/spec-helpers.js @@ -18,8 +18,9 @@ module.exports = { return Promise.all([ fs.unlinkAsync(binGrunt), fs.chmodAsync(realGrunt, parseInt('0700', 8)), - fs.symlinkAsync(realGrunt, binGrunt) - ]); + ]).then(function () { + return fs.symlinkAsync(realGrunt, binGrunt); + }); }; }, @@ -30,8 +31,9 @@ module.exports = { return Promise.all([ fs.unlinkAsync(binGulp), fs.chmodAsync(realGulp, parseInt('0700', 8)), - fs.symlinkAsync(realGulp, binGulp) - ]); + ]).then(function () { + return fs.symlinkAsync(realGulp, binGulp); + }); }; } }; From 334b50972b338e1770e26a90bb5fae2af9e9248a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 22 May 2015 16:52:52 +0200 Subject: [PATCH 037/495] Specs: Only setup gulp/grunt when required It takes quite a while to copy all those dependencies, only do it when necessary. This halved the time it took for the specs to run on my computer! --- spec/build-spec.js | 73 +++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/spec/build-spec.js b/spec/build-spec.js index 2292d874..fd1dcb4a 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -44,13 +44,6 @@ describe('Build', function() { }).then(function (dir) { directory = dir + '/'; atom.project.setPaths([ directory ]); - return specHelpers.setupNodeModules(directory)(); - }).then(function () { - return Promise.all([ - specHelpers.setupGrunt(directory)(), - specHelpers.setupGulp(directory)() - ]); - }).then(function () { return atom.packages.activatePackage('build'); }); }); @@ -204,8 +197,16 @@ describe('Build', function() { it('should show the build window', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(function () { + return Promise.resolve() + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGrunt(directory)); + }); + + runs(function () { + fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -381,8 +382,16 @@ describe('Build', function() { it('should show the build window', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(function () { + return Promise.resolve() + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGulp(directory)); + }); + + runs(function () { + fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -418,9 +427,17 @@ describe('Build', function() { it('should prioritise grunt over make', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(function () { + return Promise.resolve() + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGrunt(directory)); + }); + + runs(function () { + fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -436,9 +453,17 @@ describe('Build', function() { it('should prioritise node over grunt', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(function () { + return Promise.resolve() + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGrunt(directory)); + }); + + runs(function () { + fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); + fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -457,9 +482,17 @@ describe('Build', function() { } expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(function () { + return Promise.resolve() + .then(specHelpers.setupNodeModules(directory)) + .then(specHelpers.setupGrunt(directory)); + }); + + runs(function () { + fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); + fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); waitsFor(function() { return workspaceElement.querySelector('.build .title') && From ae6bc213bd67ccee75035d89209bf40d5c9b86c7 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 22 May 2015 16:54:47 +0200 Subject: [PATCH 038/495] Specs: Use fs-plus rather than fs-extra --- package.json | 1 - spec/build-confirm-spec.js | 2 +- spec/build-error-match-spec.js | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c8586ecb..3f5a2228 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "bluebird": "^2.9.25", "ansi-to-html": "^0.3.0", "temp": "^0.8.1", - "fs-plus": "^2.4.0", "fs-extra": "^0.18.3", "atom-space-pen-views": "^2.0.3", "xregexp": "^2.0.0", diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 61478e81..83d2be35 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -1,5 +1,5 @@ var _ = require('lodash'); -var fs = require('fs-plus'); +var fs = require('fs-extra'); var temp = require('temp'); describe('Build', function() { diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index e4426a7d..25055bac 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,4 +1,4 @@ -var fs = require('fs-plus'); +var fs = require('fs-extra'); var temp = require('temp'); describe('Build', function() { From 4bba81ede7dbbc037b48959de33fc8f326206cf4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 22 May 2015 17:00:08 +0200 Subject: [PATCH 039/495] Spec: Improved spec names --- spec/build-targets-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index ded596a0..090c9fe1 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -135,7 +135,7 @@ describe('Build', function() { }); }); - it('it should run the selected build', function () { + it('should run the selected build', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; return fs.copyAsync(file, directory + '/.atom-build.json'); @@ -163,7 +163,7 @@ describe('Build', function() { }); }); - it('it should run the default target if no selection has been made', function () { + it('should run the default target if no selection has been made', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; return fs.copyAsync(file, directory + '/.atom-build.json'); From 1453b54960c8b46a5b12606f47fe505697f074c0 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 23 May 2015 11:26:19 +0200 Subject: [PATCH 040/495] Build tools: Make sure gulp/grunt has 'default' first. To not break backwards compatability, make sure the 'default' task is the first task returned by the gulp and grunt build tools. Previously, these tools were invoked without any arguments, making them run 'default'. Now it will always invoke with an argument, so make sure 'default' is the first one to keep compatability. --- lib/tools/Grunt.js | 14 ++++---------- lib/tools/gulp.js | 5 ++++- spec/build-targets-spec.js | 2 +- spec/fixture/Gruntfile.js | 8 ++++---- spec/fixture/gulpfile.js | 8 ++++---- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 6de85920..d20a9a00 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -15,15 +15,6 @@ module.exports.isEligable = function (cwd) { return fs.existsSync(cwd + '/Gruntfile.js'); }; -module.exports.createConfig = function(cwd, args) { - var exec = fs.existsSync(cwd + '/node_modules/.bin/grunt') ? cwd + '/node_modules/.bin/grunt' : 'grunt'; - return { - exec: exec, - sh: false, - args: args - }; -}; - module.exports.settings = function (cwd) { var createConfig = function (name, args) { var exec = fs.existsSync(cwd + '/node_modules/.bin/grunt') ? cwd + '/node_modules/.bin/grunt' : 'grunt'; @@ -40,8 +31,11 @@ module.exports.settings = function (cwd) { process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); Task.once(require.resolve('./grunt-parser-task.js'), cwd, function (result) { - var config = []; + /* Make sure 'default' is the first as this will be the prioritized target */ + result.tasks.sort(function (t1, t2) { + return ('default' === t1) ? Number.NEGATIVE_INFINITY : t1.localeCompare(t2); + }); _.forEach(result.tasks || [], function (task) { config.push(createConfig('Grunt: ' + task, [ task ])); }); diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index d8c349b1..01a60aa0 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -31,8 +31,11 @@ module.exports.settings = function (cwd) { process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); Task.once(require.resolve('./gulp-parser-task.js'), cwd, function (result) { - var config = []; + /* Make sure 'default' is the first as this will be the prioritized target */ + result.tasks.sort(function (t1, t2) { + return ('default' === t1) ? -1 : t1.localeCompare(t2); + }); _.forEach(result.tasks || [], function (task) { config.push(createConfig('Gulp: ' + task, [ task ])); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 090c9fe1..4038bbc1 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -84,7 +84,7 @@ describe('Build', function() { var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { return el.textContent; }); - expect(targets).toEqual([ 'Grunt: default', 'Grunt: other task', 'Grunt: dev task' ]); + expect(targets).toEqual([ 'Grunt: default', 'Grunt: dev task', 'Grunt: other task', ]); }); }); diff --git a/spec/fixture/Gruntfile.js b/spec/fixture/Gruntfile.js index ade8cad5..5522eaf2 100644 --- a/spec/fixture/Gruntfile.js +++ b/spec/fixture/Gruntfile.js @@ -2,14 +2,14 @@ module.exports = function(grunt) { 'use strict'; grunt.initConfig({}); - grunt.registerTask('default', function() { - console.log('Surprising is the passing of time. But not so, as the time of passing'); - }); - grunt.registerTask('other task', function () { console.log('doing heavy machinery stuff'); }); + grunt.registerTask('default', function() { + console.log('Surprising is the passing of time. But not so, as the time of passing'); + }); + grunt.registerTask('dev task', function () { console.log('doing dev build'); }); diff --git a/spec/fixture/gulpfile.js b/spec/fixture/gulpfile.js index 76c6410f..f57a04b8 100644 --- a/spec/fixture/gulpfile.js +++ b/spec/fixture/gulpfile.js @@ -2,14 +2,14 @@ var gulp = require('gulp'); -gulp.task('default', function() { - console.log('gulp built'); -}); - gulp.task('dev build', function () { console.log('dev build'); }); +gulp.task('default', function() { + console.log('gulp built'); +}); + gulp.task('watch', function () { console.log('watch'); }); From b551506795e2f319ae5451924f0b1dd16a310789 Mon Sep 17 00:00:00 2001 From: Sergey Zolotarev Date: Sat, 9 May 2015 16:02:15 +0600 Subject: [PATCH 041/495] Add uniform syntax for environment variables Replace occurrences of `$XYZ` with corresponding environment variables. This basically allows you to use the same environment variable syntax in `cmd` on Windows as you would do on Linux (and probably OS X too) with `sh: true`, and thus allows you have one atom-build.json file for both platforms. --- lib/build.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index f6c0bf77..30d14938 100644 --- a/lib/build.js +++ b/lib/build.js @@ -133,6 +133,11 @@ module.exports = { }, replace: function(value) { + var env = _.extend(process.env, this.cmd.env); + value = value.replace(/\$(\w+)/, function(match, name) { + return name in env ? env[name] : match; + }); + var editor = atom.workspace.getActiveTextEditor(); if (editor && 'untitled' !== editor.getTitle()) { var activeFile = fs.realpathSync(editor.getPath()); @@ -244,7 +249,7 @@ module.exports = { list[key] = this.replace(value); }.bind(this)); - var args = _.map(this.cmd.args, this.replace); + var args = _.map(this.cmd.args, this.replace.bind(this)); this.cmd.exec = this.replace(this.cmd.exec); From a2cf51b0016ee239ab40c99e3e5715207b0e0afb Mon Sep 17 00:00:00 2001 From: Sergey Zolotarev Date: Sat, 9 May 2015 17:37:30 +0600 Subject: [PATCH 042/495] Don't modify process.env _.extend() modifies its destination operand, so pass a copy of process.env to _.extend() instead of the actual object. This fixes a bug where after deleting an environment variable from .atom-build.json it would still exist in the process.env and thus would be passed again to the child process as if it wasn't deleted at all. --- lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 30d14938..2faffb61 100644 --- a/lib/build.js +++ b/lib/build.js @@ -133,7 +133,7 @@ module.exports = { }, replace: function(value) { - var env = _.extend(process.env, this.cmd.env); + var env = _.extend(_.clone(process.env), this.cmd.env); value = value.replace(/\$(\w+)/, function(match, name) { return name in env ? env[name] : match; }); @@ -244,7 +244,7 @@ module.exports = { return; } - var env = _.extend(process.env, this.cmd.env); + var env = _.extend(_.clone(process.env), this.cmd.env); _.each(env, function(value, key, list) { list[key] = this.replace(value); }.bind(this)); From 7c562103a3ab32cac615b42b8fe404a97be07857 Mon Sep 17 00:00:00 2001 From: Sergey Zolotarev Date: Sat, 23 May 2015 22:11:17 +0600 Subject: [PATCH 043/495] Extend replace test --- spec/build-spec.js | 2 ++ spec/fixture/.atom-build.replace.json | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/build-spec.js b/spec/build-spec.js index d0f5d210..94be3f36 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -488,6 +488,7 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); + process.env.FROM_PROCESS_ENV = '{FILE_ACTIVE}'; fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(replaceAtomBuildFile)); waitsForPromise(function() { @@ -509,6 +510,7 @@ describe('Build', function() { expect(output.indexOf('PROJECT_PATH=' + directory.substring(0, -1))).not.toBe(-1); expect(output.indexOf('FILE_ACTIVE=' + directory + '.atom-build.json')).not.toBe(-1); expect(output.indexOf('FROM_ENV=' + directory + '.atom-build.json')).not.toBe(-1); + expect(output.indexOf('FROM_PROCESS_ENV=' + directory + '.atom-build.json')).not.toBe(-1); expect(output.indexOf('FILE_ACTIVE_NAME=.atom-build.json')).not.toBe(-1); expect(output.indexOf('FILE_ACTIVE_NAME_BASE=.atom-build')).not.toBe(-1); }); diff --git a/spec/fixture/.atom-build.replace.json b/spec/fixture/.atom-build.replace.json index b5567ef4..adfe1c01 100644 --- a/spec/fixture/.atom-build.replace.json +++ b/spec/fixture/.atom-build.replace.json @@ -6,7 +6,8 @@ "REPO_BRANCH_SHORT={REPO_BRANCH_SHORT}", "FILE_ACTIVE_NAME={FILE_ACTIVE_NAME}", "FILE_ACTIVE_NAME_BASE={FILE_ACTIVE_NAME_BASE}", - "FROM_ENV=$FROM_ENV" + "FROM_ENV=$FROM_ENV", + "FROM_PROCESS_ENV=$FROM_PROCESS_ENV" ], "env": { "FROM_ENV": "{FILE_ACTIVE}" From 09a248c10307247afbe74d38cef380c6c758acf9 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 24 May 2015 10:28:29 +0200 Subject: [PATCH 044/495] README: Added documentation about targets --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 05550a19..f0dff7d3 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,9 @@ Supported build tools: 1. [NodeJS](http://nodejs.org) (runs `npm install`) - if `package.json` exists where `engines['node']` is set 1. [Atom](http://atom.io) (runs `apm install`) - if `package.json` exists where `engines['atom']` is set 1. [Grunt](http://gruntjs.com/) - if `Gruntfile.js` exists + * Extract targets 1. [Gulp](http://gulpjs.com/) - if `gulpfile.js` exists + * Extract targets 1. [GNU Make](https://www.gnu.org/software/make/) - if `Makefile` exists 1. [Elixir](http://elixir-lang.org/) - if `mix.exs` exists 1. [Cargo](http://doc.crates.io) - if `Cargo.toml` exists @@ -41,6 +43,7 @@ exactly what to execute. Create a file named `.atom-build.json` in your project { "cmd": "", + "name": "", "args": [ "", "", ... ], "sh": true, "cwd": "", @@ -49,7 +52,13 @@ exactly what to execute. Create a file named `.atom-build.json` in your project "VARIABLE2": "VALUE2", ... }, - "errorMatch": "^regexp$" + "errorMatch": "^regexp$", + "targets": { + "": { + "cmd": "", + ... (all previous options are viable here except `targets`) + } + } } Note that if `sh` is false `cmd` must only be the executable - no arguments here. If the @@ -61,11 +70,13 @@ systems). ### Configuration options * `cmd` - **[required]** The executable command + * `name` - **[optional]** The name of the targets. Viewed in the targets list (toggled by `build:select-active-target`). * `args` - **[optional]** An array of arguments for the command * `sh` - **[optional]** If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. * `cwd` - **[optional]** The working directory for the command. E.g. what `.` resolves to. * `env` - **[optional]** An array of environment variables and their values to set * `errorMatch` - **[optional]** A regular expression to match output to a file, row and col. See [Error matching](#error-match) for details. + * `targets`- **[optional]** Additional targets which can be used to build variations of your project. ### Replacements From 8e5e256fc6d76277c5e1062233e8d0c09801b02f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 24 May 2015 11:19:21 +0200 Subject: [PATCH 045/495] Spec: added tests for stealFocus --- spec/build-spec.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spec/build-spec.js b/spec/build-spec.js index 94be3f36..00902902 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -34,6 +34,7 @@ describe('Build', function() { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); + atom.config.set('build.stealFocus', true); // Set up dependencies fs.copySync(path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules')); @@ -618,4 +619,40 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).toExist(); }); }); + + describe('when build is triggered, focus should adhere the stealFocus config', function () { + it('should focus the build panel if stealFocus is true', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build'); + }); + + runs(function() { + expect(document.activeElement).toHaveClass('build'); + }); + }); + + it('should leave focus untouched if stealFocus is false', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + atom.config.set('build.stealFocus', false); + var activeElement = document.activeElement; + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build'); + }); + + runs(function() { + expect(document.activeElement).toEqual(activeElement); + expect(document.activeElement).not.toHaveClass('build'); + }); + }); + }); }); From 95eac50340c4e2b79e07ae5c7c815c784619df4b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 24 May 2015 11:26:51 +0200 Subject: [PATCH 046/495] Prepare 0.35.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 16fda8ed..49828958 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.34.0", + "version": "0.35.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 6bda052e05d4306526873a8255e116056c4f74a8 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 27 May 2015 21:36:41 +0200 Subject: [PATCH 047/495] Style: kebab-case for file names --- lib/build-view.js | 2 +- lib/build.js | 2 +- lib/{GoogleAnalytics.js => google-analytics.js} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename lib/{GoogleAnalytics.js => google-analytics.js} (100%) diff --git a/lib/build-view.js b/lib/build-view.js index a7fc0719..18badf2e 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -3,7 +3,7 @@ var _ = require('lodash'); var View = require('atom-space-pen-views').View; var cscompatability = require('./cscompatability'); -var GoogleAnalytics = require('./GoogleAnalytics'); +var GoogleAnalytics = require('./google-analytics'); var Convert = require('ansi-to-html'); module.exports = (function() { diff --git a/lib/build.js b/lib/build.js index 5a2ed800..3f0b1a57 100644 --- a/lib/build.js +++ b/lib/build.js @@ -10,7 +10,7 @@ var XRegExp = require('xregexp').XRegExp; var SaveConfirmView = require('./save-confirm-view'); var TargetsView = require('./targets-view'); var BuildView = require('./build-view'); -var GoogleAnalytics = require('./GoogleAnalytics'); +var GoogleAnalytics = require('./google-analytics'); var tools = require('./tools'); function NoToolError() { diff --git a/lib/GoogleAnalytics.js b/lib/google-analytics.js similarity index 100% rename from lib/GoogleAnalytics.js rename to lib/google-analytics.js From f02ecb5227694e1f66606104b7d7248a82ae4f40 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 27 May 2015 21:40:31 +0200 Subject: [PATCH 048/495] Use generic path.set and path.join To get paths valid for windows as well, use the capabilities of the build in 'path' tool, which is platform-aware. --- lib/tools/Grunt.js | 5 +++-- lib/tools/atom-build.js | 9 +++++---- lib/tools/gulp.js | 5 +++-- lib/tools/make.js | 7 ++++--- lib/tools/npm_apm.js | 11 ++++++----- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index d20a9a00..eeb6855d 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -12,12 +12,13 @@ var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'Grunt'; module.exports.isEligable = function (cwd) { - return fs.existsSync(cwd + '/Gruntfile.js'); + return fs.existsSync(path.join(cwd, 'Gruntfile.js')); }; module.exports.settings = function (cwd) { var createConfig = function (name, args) { - var exec = fs.existsSync(cwd + '/node_modules/.bin/grunt') ? cwd + '/node_modules/.bin/grunt' : 'grunt'; + var localPath = path.join(cwd, 'node_modules', '.bin', 'grunt'); + var exec = fs.existsSync(localPath) ? localPath : 'grunt'; return { name: name, exec: exec, diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index e3b522e9..e266c185 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -1,16 +1,17 @@ 'use strict'; +var path = require('path'); var fs = require('fs'); var _ = require('lodash'); module.exports.niceName = 'Custom file (.atom-build.json)'; -module.exports.isEligable = function (path) { - return fs.existsSync(path + '/.atom-build.json'); +module.exports.isEligable = function (cwd) { + return fs.existsSync(path.join(cwd, '.atom-build.json')); }; -module.exports.settings = function (path) { - var realAtomBuild = fs.realpathSync(path + '/.atom-build.json'); +module.exports.settings = function (cwd) { + var realAtomBuild = fs.realpathSync(cwd + '/.atom-build.json'); delete require.cache[realAtomBuild]; var createBuildConfig = function(build, name) { diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 01a60aa0..a9a53054 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -12,12 +12,13 @@ var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'gulp'; module.exports.isEligable = function (cwd) { - return fs.existsSync(cwd + '/gulpfile.js'); + return fs.existsSync(path.join(cwd, 'gulpfile.js')); }; module.exports.settings = function (cwd) { var createConfig = function (name, args) { - var exec = fs.existsSync(cwd + '/node_modules/.bin/gulp') ? cwd + '/node_modules/.bin/gulp' : 'gulp'; + var localPath = path.join(cwd, 'node_modules', '.bin', 'gulp'); + var exec = fs.existsSync(localPath) ? localPath : 'gulp'; return { name: name, exec: exec, diff --git a/lib/tools/make.js b/lib/tools/make.js index ee2928ed..2a44ebf6 100644 --- a/lib/tools/make.js +++ b/lib/tools/make.js @@ -1,14 +1,15 @@ 'use strict'; +var path = require('path'); var fs = require('fs'); module.exports.niceName = 'GNU Make'; -module.exports.isEligable = function (path) { - return fs.existsSync(path + '/Makefile'); +module.exports.isEligable = function (cwd) { + return fs.existsSync(path.join(cwd, 'Makefile')); }; -module.exports.settings = function (path) { +module.exports.settings = function (cwd) { return [ { name: 'GNU Make: default', exec: 'make', diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index 0bf3f072..0bed2d54 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -1,15 +1,16 @@ 'use strict'; +var path = require('path'); var fs = require('fs'); module.exports.niceName = 'npm or apm'; -module.exports.isEligable = function (path) { - if (!fs.existsSync(path + '/package.json')) { +module.exports.isEligable = function (cwd) { + if (!fs.existsSync(path.join(cwd, 'package.json'))) { return false; } - var realPackage = fs.realpathSync(path + '/package.json'); + var realPackage = fs.realpathSync(path.join(cwd, 'package.json')); delete require.cache[realPackage]; var pkg = require(realPackage); @@ -20,8 +21,8 @@ module.exports.isEligable = function (path) { return true; }; -module.exports.settings = function (path) { - var realPackage = fs.realpathSync(path + '/package.json'); +module.exports.settings = function (cwd) { + var realPackage = fs.realpathSync(path.join(cwd, 'package.json')); var pkg = require(realPackage); return { From 5a12d28d2ed36f01b1582869b2c3bee61d75e20d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 28 May 2015 16:16:29 +0200 Subject: [PATCH 049/495] Tools: Gulp, Grunt and NPM/APM: use '.cmd' extension When running on windows, use 'cmd' extension for commands to run. --- lib/tools/Grunt.js | 5 +++-- lib/tools/gulp.js | 5 +++-- lib/tools/npm_apm.js | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index eeb6855d..9d649a0b 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -17,8 +17,9 @@ module.exports.isEligable = function (cwd) { module.exports.settings = function (cwd) { var createConfig = function (name, args) { - var localPath = path.join(cwd, 'node_modules', '.bin', 'grunt'); - var exec = fs.existsSync(localPath) ? localPath : 'grunt'; + var executable = /^win/.test(process.platform) ? 'grunt.cmd' : 'grunt'; + var localPath = path.join(cwd, 'node_modules', '.bin', executable); + var exec = fs.existsSync(localPath) ? localPath : executable; return { name: name, exec: exec, diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index a9a53054..d0e572ef 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -17,8 +17,9 @@ module.exports.isEligable = function (cwd) { module.exports.settings = function (cwd) { var createConfig = function (name, args) { - var localPath = path.join(cwd, 'node_modules', '.bin', 'gulp'); - var exec = fs.existsSync(localPath) ? localPath : 'gulp'; + var executable = /^win/.test(process.platform) ? 'gulp.cmd' : 'gulp'; + var localPath = path.join(cwd, 'node_modules', '.bin', executable); + var exec = fs.existsSync(localPath) ? localPath : executable; return { name: name, exec: exec, diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index 0bed2d54..f671201e 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -25,9 +25,10 @@ module.exports.settings = function (cwd) { var realPackage = fs.realpathSync(path.join(cwd, 'package.json')); var pkg = require(realPackage); + var executableExtension = /^win/.test(process.platform) ? '.cmd' : ''; return { name: pkg.engines.node ? 'npm' : 'apm', - exec: pkg.engines.node ? 'npm' : 'apm', + exec: (pkg.engines.node ? 'npm' : 'apm') + executableExtension, args: [ '--color=always', 'install' ], sh: false }; From 4f81a4c8b7c9915b92c342dbbe6902245a7048dc Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 28 May 2015 19:34:45 +0200 Subject: [PATCH 050/495] Build tools: Gulp/Grunt - better error messages --- lib/build.js | 4 ++-- lib/tools/Grunt.js | 2 +- lib/tools/grunt-parser-task.js | 2 +- lib/tools/gulp-parser-task.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/build.js b/lib/build.js index 3f0b1a57..0de2fab5 100644 --- a/lib/build.js +++ b/lib/build.js @@ -198,7 +198,7 @@ module.exports = { }).catch(NoToolError, function (error) { targetsView.setError(error.message); }).catch(function (error) { - targetsView.setError('Something went wrong: ' + error.message); + targetsView.setError(error.message); }); }, @@ -364,7 +364,7 @@ module.exports = { }).catch(SyntaxError, function (error) { this.buildView.errorMessage('You have a syntax error in your build file.', error.message); }).catch(function (error) { - this.buildView.errorMessage('Ooops. Something went wrong.', error.message + '\n' + error.stack); + this.buildView.errorMessage('Ooops. Something went wrong.', error.message + (error.stack ? '\n' + error.stack : '')); }); }, diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index d20a9a00..38244c3e 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -34,7 +34,7 @@ module.exports.settings = function (cwd) { var config = []; /* Make sure 'default' is the first as this will be the prioritized target */ result.tasks.sort(function (t1, t2) { - return ('default' === t1) ? Number.NEGATIVE_INFINITY : t1.localeCompare(t2); + return ('default' === t1) ? -1 : t1.localeCompare(t2); }); _.forEach(result.tasks || [], function (task) { config.push(createConfig('Grunt: ' + task, [ task ])); diff --git a/lib/tools/grunt-parser-task.js b/lib/tools/grunt-parser-task.js index cae337b8..48d338de 100644 --- a/lib/tools/grunt-parser-task.js +++ b/lib/tools/grunt-parser-task.js @@ -27,6 +27,6 @@ module.exports = function (path) { require(path + '/Gruntfile.js')(grunt); return { tasks: Object.keys(grunt.task._tasks) }; } catch (e) { - return { error: e }; + return { error: { message: e.message } }; } }; diff --git a/lib/tools/gulp-parser-task.js b/lib/tools/gulp-parser-task.js index b0468cf6..f3cb1021 100644 --- a/lib/tools/gulp-parser-task.js +++ b/lib/tools/gulp-parser-task.js @@ -27,6 +27,6 @@ module.exports = function (path) { require(path + '/gulpfile.js'); return { tasks: Object.keys(gulp.tasks) }; } catch (e) { - return { error: e }; + return { error: { message: e.message } }; } }; From fde35de32b622e0bd0f11b33d191d793ffdf627b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 28 May 2015 19:35:10 +0200 Subject: [PATCH 051/495] Specs: Tests for gulp/grunt error message if not installed --- spec/build-spec.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/spec/build-spec.js b/spec/build-spec.js index 6e49f109..43b112ae 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -219,6 +219,21 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time. But not so, as the time of passing/); }); }); + + it('should tell the user that Grunt is not installed if it is not', function () { + fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').textContent).toEqual('Grunt is not installed.'); + }); + }); }); describe('when build is triggered with package.json file', function() { @@ -404,6 +419,21 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/gulp built/); }); }); + + it('should tell the user that gulp is not installed if it is not', function () { + fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').textContent).toEqual('Gulp is not installed.'); + }); + }); }); describe('when multiple build options are available', function() { From f4266858aaad7b28e3b298f0d533ef75d4e87b33 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 28 May 2015 19:46:19 +0200 Subject: [PATCH 052/495] Build tools: Run default target upon targets failure Gulp and grunt should run its default targets even if the extraction of targets fails. Build can only extract targets if gulp or grunt is installed locally in the project root. However, it may still be possible to execute the build with a global installation. --- lib/tools/Grunt.js | 4 ++++ lib/tools/gulp.js | 4 ++++ spec/build-spec.js | 10 ++++----- spec/build-targets-spec.js | 46 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 38244c3e..f4748929 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -31,6 +31,10 @@ module.exports.settings = function (cwd) { process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); Task.once(require.resolve('./grunt-parser-task.js'), cwd, function (result) { + if (result.error) { + return resolve([ createConfig('Grunt: default', [ 'default' ]) ]); + } + var config = []; /* Make sure 'default' is the first as this will be the prioritized target */ result.tasks.sort(function (t1, t2) { diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 01a60aa0..25c94888 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -31,6 +31,10 @@ module.exports.settings = function (cwd) { process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); Task.once(require.resolve('./gulp-parser-task.js'), cwd, function (result) { + if (result.error) { + return resolve([ createConfig('Gulp: default', [ 'default' ]) ]); + } + var config = []; /* Make sure 'default' is the first as this will be the prioritized target */ result.tasks.sort(function (t1, t2) { diff --git a/spec/build-spec.js b/spec/build-spec.js index 43b112ae..2678d648 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -220,7 +220,7 @@ describe('Build', function() { }); }); - it('should tell the user that Grunt is not installed if it is not', function () { + it('should run default target if grunt is not installed', function () { fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); atom.commands.dispatch(workspaceElement, 'build:trigger'); @@ -230,8 +230,7 @@ describe('Build', function() { }); runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toEqual('Grunt is not installed.'); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: grunt/); }); }); }); @@ -420,7 +419,7 @@ describe('Build', function() { }); }); - it('should tell the user that gulp is not installed if it is not', function () { + it('should run default target if gulp is not installed', function () { fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile)); atom.commands.dispatch(workspaceElement, 'build:trigger'); @@ -430,8 +429,7 @@ describe('Build', function() { }); runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toEqual('Gulp is not installed.'); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: gulp/); }); }); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 4038bbc1..19dfac44 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -237,4 +237,50 @@ describe('Build', function() { }); }); }); + + describe('when a tool is unable to extract targets', function () { + it('should still list the default target for gulp', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/gulpfile.js'; + return fs.copyAsync(file, directory + '/gulpfile.js'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'Gulp: default' ]); + }); + }); + + it('should still list the default target for Grunt', function () { + waitsForPromise(function () { + var file = __dirname + '/fixture/Gruntfile.js'; + return fs.copyAsync(file, directory + '/Gruntfile.js'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'Grunt: default' ]); + }); + }); + }); }); From 4f3da5a67ebd98bbf0a5e35bdb8fd51380f467b1 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Jun 2015 19:59:18 +0200 Subject: [PATCH 053/495] README: Fixed supporter build tool capabilities --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f0dff7d3..f54d1cda 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,14 @@ Automatically build your project inside your new favorite editor, Atom. Supported build tools: 1. Custom by [specifying your own build command](#custom-build-command) + * Supports multiple targets. + * Supports error matching. 1. [NodeJS](http://nodejs.org) (runs `npm install`) - if `package.json` exists where `engines['node']` is set 1. [Atom](http://atom.io) (runs `apm install`) - if `package.json` exists where `engines['atom']` is set 1. [Grunt](http://gruntjs.com/) - if `Gruntfile.js` exists - * Extract targets + * Supports multiple targets. 1. [Gulp](http://gulpjs.com/) - if `gulpfile.js` exists - * Extract targets + * Supports multiple targets. 1. [GNU Make](https://www.gnu.org/software/make/) - if `Makefile` exists 1. [Elixir](http://elixir-lang.org/) - if `mix.exs` exists 1. [Cargo](http://doc.crates.io) - if `Cargo.toml` exists From 574a2941dbbb64d5f669917447a3144fc8255b2f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Jun 2015 20:44:36 +0200 Subject: [PATCH 054/495] Build: Keep custom build file live Since the introduction of build targets, the selected target was cached in memory. This caused alterations made to e.g. the custom build file to not have any effect until Atom was restarted. This fix refreshes targets when the custom file is altered. --- lib/build.js | 18 +++++++++++++++++- spec/build-spec.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 0de2fab5..83e49e78 100644 --- a/lib/build.js +++ b/lib/build.js @@ -1,7 +1,8 @@ 'use strict'; var child_process = require('child_process'); -var fs = require('fs'); +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var _ = require('lodash'); var Promise = require('bluebird'); @@ -115,6 +116,9 @@ module.exports = { deactivate: function() { GoogleAnalytics.sendEvent('core', 'deactivated'); + if (this.customFileWatcher) { + this.customFileWatcher.close(); + } if (this.child) { this.child.kill('SIGKILL'); } @@ -148,9 +152,21 @@ module.exports = { refreshTargets: function() { var path = this.activePath(); var prioritizedTarget; + var customFile = path + '/.atom-build.json'; + + if (this.customFileWatcher) { + this.customFileWatcher.close(); + this.customFileWatcher = undefined; + } return Promise.resolve(tools) .bind(this) + .then(function () { + this.customFileWatcher = fs.watch(customFile, function () { + this.refreshTargets(); + }.bind(this)); + }) + .catch(function(err) { /* Unable to watch file. Updates to custom file will require manual refresh */ }) .then(function () { return _.filter(tools, function (tool) { return tool.isEligable(path); diff --git a/spec/build-spec.js b/spec/build-spec.js index 2678d648..49efd71e 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -391,6 +391,49 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build .title').textContent).toBe('You have a syntax error in your build file.'); }); }); + + it('should not cache the contents of the build file', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo first' + })); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/first/); + }); + + waitsFor(function () { + return !workspaceElement.querySelector('.build .title'); + }); + + runs(function () { + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo second' + })); + }); + + waits(100); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/second/); + }); + }); }); describe('when build is triggered with gulp file', function() { From 8a21d1d7a340e9ce2a3d6abd4d93db60c6c3ac20 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Jun 2015 21:39:28 +0200 Subject: [PATCH 055/495] Prepare 0.36.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ca6870d9..af433ba2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.35.0", + "version": "0.36.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 815d01e9cb9967c0c48ed8ae5a8207a546e73bc6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Jun 2015 21:48:03 +0200 Subject: [PATCH 056/495] Build tools: gulp/grunt always sort 'default' first. --- lib/tools/Grunt.js | 8 +++++++- lib/tools/gulp.js | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 39116296..0896b629 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -40,7 +40,13 @@ module.exports.settings = function (cwd) { var config = []; /* Make sure 'default' is the first as this will be the prioritized target */ result.tasks.sort(function (t1, t2) { - return ('default' === t1) ? -1 : t1.localeCompare(t2); + if ('default' === t1) { + return -1; + } + if ('default' === t2) { + return 1; + } + return t1.localeCompare(t2); }); _.forEach(result.tasks || [], function (task) { config.push(createConfig('Grunt: ' + task, [ task ])); diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 2b7a018e..261e6bdf 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -40,7 +40,13 @@ module.exports.settings = function (cwd) { var config = []; /* Make sure 'default' is the first as this will be the prioritized target */ result.tasks.sort(function (t1, t2) { - return ('default' === t1) ? -1 : t1.localeCompare(t2); + if ('default' === t1) { + return -1; + } + if ('default' === t2) { + return 1; + } + return t1.localeCompare(t2); }); _.forEach(result.tasks || [], function (task) { config.push(createConfig('Gulp: ' + task, [ task ])); From 29a8f0f92e9eb6f81634a6c2ffe60609f73348bc Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Jun 2015 21:53:58 +0200 Subject: [PATCH 057/495] Prepare 0.36.1 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af433ba2..9d2aeb5c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.36.0", + "version": "0.36.1", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From eb69fa5b5392c72ccdbc413e010400609bb49038 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 3 Jun 2015 20:57:54 +0200 Subject: [PATCH 058/495] Refactor error-matching to module Instead of bloating build.js with all functionality, move error-matching to a module of its own, with a clear interface to use. --- lib/build.js | 79 +++-------------------------- lib/error-matcher.js | 92 ++++++++++++++++++++++++++++++++++ spec/build-error-match-spec.js | 2 +- 3 files changed, 100 insertions(+), 73 deletions(-) create mode 100644 lib/error-matcher.js diff --git a/lib/build.js b/lib/build.js index 83e49e78..fa9f103e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -6,12 +6,12 @@ var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var _ = require('lodash'); var Promise = require('bluebird'); -var XRegExp = require('xregexp').XRegExp; var SaveConfirmView = require('./save-confirm-view'); var TargetsView = require('./targets-view'); var BuildView = require('./build-view'); var GoogleAnalytics = require('./google-analytics'); +var ErrorMatcher = require('./error-matcher'); var tools = require('./tools'); function NoToolError() { @@ -88,10 +88,10 @@ module.exports = { this.match = []; this.stdout = new Buffer(0); this.stderr = new Buffer(0); + this.errorMatcher = new ErrorMatcher(); + atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this)); atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); - atom.commands.add('atom-workspace', 'build:error-match', this.errorMatch.bind(this)); - atom.commands.add('atom-workspace', 'build:error-match-first', this.errorMatchFirst.bind(this)); atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this)); atom.commands.add('atom-workspace', 'build:confirm', function() { GoogleAnalytics.sendEvent('build', 'confirmed'); @@ -111,6 +111,8 @@ module.exports = { }); }); + this.errorMatcher.on('error', this.buildView.errorMessage.bind(this.buildView, 'Error matching failed!')); + GoogleAnalytics.sendEvent('core', 'activated'); }, @@ -241,75 +243,6 @@ module.exports = { return value; }, - errorParse: function() { - this.match = []; - var regex = XRegExp(this.cmd.errorMatch); - - var matchErr, matchOut; - - matchErr = XRegExp.forEach(this.stderr.toString('utf8'), regex, function (match) { - return this.push(match); - }, []); - - matchOut = XRegExp.forEach(this.stdout.toString('utf8'), regex, function (match) { - return this.push(match); - }, []); - - this.match = matchErr.concat(matchOut); - }, - - errorMatchGoTo: function () { - var file = this.replace(this.cmd.cwd) + path.sep + this.match[0].file; - if (!this.match[0].file) { - file = this.match[0].absFile; - } - var row = this.match[0].line ? this.match[0].line - 1 : 0; /* Because atom is zero-based */ - var col = this.match[0].col ? this.match[0].col - 1 : 0; /* Because atom is zero-based */ - - fs.exists(file, function (exists) { - if (!exists) { - this.buildView.errorMessage('Error matching failed:', 'Matched file does not exist: ' + file); - return; - } - - atom.workspace.open(file, { - initialLine: row, - initialColumn: col - }); - }.bind(this)); - }, - - errorMatch: function() { - GoogleAnalytics.sendEvent('errorMatch', 'match'); - if (!this.cmd.errorMatch) { - return; - } - - if (this.match.length === 0) { - this.errorParse(); - if (this.match.length === 0) { - return; - } - } - - this.errorMatchGoTo(); - this.match.push(this.match.shift()); - }, - - errorMatchFirst: function() { - GoogleAnalytics.sendEvent('errorMatch', 'first'); - if (!this.cmd.errorMatch) { - return; - } - this.errorParse(); - if (this.match.length === 0) { - return; - } - - this.errorMatchGoTo(); - this.match.push(this.match.shift()); - }, - startNewBuild: function() { this.cmd = {}; this.match = []; @@ -368,6 +301,8 @@ module.exports = { this.buildView.detach(); }.bind(this), 1000); } else { + var t = this.targets[this.activeTarget]; + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), Buffer.concat([ this.stdout, this.stderr ]).toString('utf8')); GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; diff --git a/lib/error-matcher.js b/lib/error-matcher.js new file mode 100644 index 00000000..335cdb7e --- /dev/null +++ b/lib/error-matcher.js @@ -0,0 +1,92 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var XRegExp = require('xregexp').XRegExp; +var GoogleAnalytics = require('./google-analytics'); +var EventEmitter = require('events').EventEmitter; +var util = require('util'); + +module.exports = (function () { + + function ErrorMatcher() { + this.regex = null; + this.cwd = null; + this.stdout = null; + this.stderr = null; + this.currentMatch = []; + + atom.commands.add('atom-workspace', 'build:error-match', this.match.bind(this)); + atom.commands.add('atom-workspace', 'build:error-match-first', this.matchFirst.bind(this)); + } + + util.inherits(ErrorMatcher, EventEmitter); + + ErrorMatcher.prototype._goto = function () { + var file = this.cwd + path.sep + this.currentMatch[0].file; + if (!this.currentMatch[0].file) { + file = this.currentMatch[0].absFile; + } + if (!file) { + return this.emit('error', 'Did not match any file. Don\'t know what to open.'); + } + + var row = this.currentMatch[0].line ? this.currentMatch[0].line - 1 : 0; /* Because atom is zero-based */ + var col = this.currentMatch[0].col ? this.currentMatch[0].col - 1 : 0; /* Because atom is zero-based */ + + fs.exists(file, function (exists) { + if (!exists) { + return this.emit('error', 'Matched file does not exist: ' + file); + } + atom.workspace.open(file, { + initialLine: row, + initialColumn: col + }); + this.currentMatch.push(this.currentMatch.shift()); + }.bind(this)); + }; + + ErrorMatcher.prototype._parse = function () { + this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match) { + this.push(match); + }, []); + return this.currentMatch.length; + }; + + ErrorMatcher.prototype.set = function (regex, cwd, output) { + this.regex = XRegExp(regex); + this.cwd = cwd; + this.output = output; + this.currentMatch = []; + }; + + ErrorMatcher.prototype.match = function () { + if (!this.regex) { + return; + } + + GoogleAnalytics.sendEvent('errorMatch', 'match'); + + if (0 === this.currentMatch.length && 0 === this._parse()) { + return; + } + + this._goto(); + }; + + ErrorMatcher.prototype.matchFirst = function () { + if (!this.regex) { + return; + } + + GoogleAnalytics.sendEvent('errorMatch', 'first'); + + if (0 === this._parse()) { + return; + } + + this._goto(); + }; + + return ErrorMatcher; +})(); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 25055bac..49610938 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -85,7 +85,7 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').textContent === 'Error matching failed:'; + return workspaceElement.querySelector('.build .title').textContent === 'Error matching failed!'; }); runs(function() { From f2163acf91aa3ef9dc3adbeea06a41495bb74452 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 3 Jun 2015 21:17:54 +0200 Subject: [PATCH 059/495] GA: Changed events Do not track activated or deactivated. Do track the package version number. --- lib/build.js | 4 +--- lib/google-analytics.js | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index fa9f103e..91728f82 100644 --- a/lib/build.js +++ b/lib/build.js @@ -112,12 +112,9 @@ module.exports = { }); this.errorMatcher.on('error', this.buildView.errorMessage.bind(this.buildView, 'Error matching failed!')); - - GoogleAnalytics.sendEvent('core', 'activated'); }, deactivate: function() { - GoogleAnalytics.sendEvent('core', 'deactivated'); if (this.customFileWatcher) { this.customFileWatcher.close(); } @@ -176,6 +173,7 @@ module.exports = { }) .then(function (tools) { return Promise.all(_.map(tools, function (tool) { + GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); return tool.settings(path); })); }) diff --git a/lib/google-analytics.js b/lib/google-analytics.js index 64a9a94a..e3ebb459 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -5,6 +5,12 @@ var querystring = require('querystring'); var cid; module.exports = (function () { + atom.packages.onDidActivatePackage(function (pkg) { + if ('metrics' === pkg.name) { + var buildPackage = atom.packages.getLoadedPackage('build'); + GoogleAnalytics.sendEvent('core', 'activated', buildPackage.metadata.version); + } + }); function GoogleAnalytics () {} GoogleAnalytics.getCid = function (cb) { From 6bb53ee67538f05fd77d235940b2f7d144304718 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 3 Jun 2015 21:21:05 +0200 Subject: [PATCH 060/495] README: Updated analytics section --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f54d1cda..1548ca20 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ package is most important and what parts can be removed. The data is fully anonymous and can not be tracked back to you in any way. This is what is collected + * Version of package used. * Build triggered, succeeded or failed. * Which build tool was used. * Visibility of UI components. From a1bedd97aea922e5c6ae3457400c9fa0180de716 Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Thu, 4 Jun 2015 10:45:05 +0200 Subject: [PATCH 061/495] Added simple scrolling function to the build panel on error match --- lib/build-view.js | 10 ++++++++++ lib/build.js | 10 +++++++++- lib/error-matcher.js | 13 ++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 18badf2e..eebdc9c8 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -190,5 +190,15 @@ module.exports = (function() { this.output.scrollTop(this.output[0].scrollHeight); }; + BuildView.prototype.replace = function(text) { + this.output.empty(); + this.output.append(text); + }; + + BuildView.prototype.scrollTo = function(marker) { + var position = this.output.find('#' + marker).position(); + this.output.scrollTop(position.top + this.output.scrollTop()); + }; + return BuildView; })(); diff --git a/lib/build.js b/lib/build.js index 91728f82..5b93d73c 100644 --- a/lib/build.js +++ b/lib/build.js @@ -112,6 +112,14 @@ module.exports = { }); this.errorMatcher.on('error', this.buildView.errorMessage.bind(this.buildView, 'Error matching failed!')); + + this.errorMatcher.on('scroll', function(marker) { + this.buildView.scrollTo(marker); + }.bind(this)); + + this.errorMatcher.on('replace', function(text) { + this.buildView.replace(text); + }.bind(this)); }, deactivate: function() { @@ -300,7 +308,7 @@ module.exports = { }.bind(this), 1000); } else { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), Buffer.concat([ this.stdout, this.stderr ]).toString('utf8')); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.context.innerHTML); GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 335cdb7e..ad1abb46 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -42,14 +42,25 @@ module.exports = (function () { initialLine: row, initialColumn: col }); + this.emit('scroll', this.currentMatch[0].marker); + this.currentMatch.push(this.currentMatch.shift()); }.bind(this)); }; ErrorMatcher.prototype._parse = function () { - this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match) { + this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match, i) { + match.marker = i; this.push(match); }, []); + var output = this.output; + var matchIndex; + for (matchIndex in this.currentMatch) { + var search = this.currentMatch[matchIndex][0]; + var replace = '' + this.currentMatch[matchIndex][0] + ''; + output = XRegExp.replace(output, search, replace); + } + this.emit('replace', output); return this.currentMatch.length; }; From ce8ee9c8cf534069cf802417814abcd82e67dda6 Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Thu, 4 Jun 2015 11:05:57 +0200 Subject: [PATCH 062/495] Invoke error parsing on failed build --- lib/build.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 91728f82..c9e483c0 100644 --- a/lib/build.js +++ b/lib/build.js @@ -47,12 +47,19 @@ module.exports = { default: false, order: 3 }, + scrollOnError: { + title: 'Automatically scroll on build error', + description: 'Automatically scroll to first matched error when a build failed.', + type: 'boolean', + default: false, + order: 4 + }, stealFocus: { title: 'Steal Focus', description: 'Steal focus when opening build panel.', type: 'boolean', default: true, - order: 4 + order: 5 }, monocleHeight: { title: 'Monocle Height', @@ -61,7 +68,7 @@ module.exports = { default: 0.75, minimum: 0.1, maximum: 0.9, - order: 5 + order: 6 }, minimizedHeight: { title: 'Minimized Height', @@ -70,7 +77,7 @@ module.exports = { default: 0.15, minimum: 0.1, maximum: 0.9, - order: 6 + order: 7 } }, @@ -301,6 +308,9 @@ module.exports = { } else { var t = this.targets[this.activeTarget]; this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), Buffer.concat([ this.stdout, this.stderr ]).toString('utf8')); + if (atom.config.get('build.scrollOnError')) { + this.errorMatcher.matchFirst(); + } GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; From 5300ab40cfc626f45a4bd5e815554ba3c33738a1 Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Sat, 6 Jun 2015 10:49:26 +0200 Subject: [PATCH 063/495] Added test for auto scroll on error config --- spec/build-error-match-spec.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 49610938..47127251 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -267,7 +267,33 @@ describe('Build', function() { var editor = atom.workspace.getActiveTextEditor(); expect(editor.getPath()).toEqual(directory + '.atom-build.json'); }); + }); + + it('should auto match error on failed build when config is set', function () { + atom.config.set('build.scrollOnError', true); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + waitsFor(function () { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + }); + atom.config.set('build.scrollOnError', true); }); }); }); From a1b22dbc57cfa52a5e11f12430407223ba1de69a Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Sun, 7 Jun 2015 00:55:34 +0200 Subject: [PATCH 064/495] Add scrollTo type and code cleanup - BuildView.scrollTo now needs a type (html class) in addition to the id (html id) - In ErrorMatcher._goto moved currentMatch[0] into extra variable to make the code not as cluttered --- lib/build-view.js | 9 ++++++--- lib/build.js | 4 ++-- lib/error-matcher.js | 20 +++++++++++--------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index eebdc9c8..879ac6ae 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -195,9 +195,12 @@ module.exports = (function() { this.output.append(text); }; - BuildView.prototype.scrollTo = function(marker) { - var position = this.output.find('#' + marker).position(); - this.output.scrollTop(position.top + this.output.scrollTop()); + BuildView.prototype.scrollTo = function(type, id) { + var interim = this.output.find('.' + type + '#' + id); + var position = interim.position(); + if (position) { + this.output.scrollTop(position.top + this.output.scrollTop()); + } }; return BuildView; diff --git a/lib/build.js b/lib/build.js index 5b93d73c..72996d6d 100644 --- a/lib/build.js +++ b/lib/build.js @@ -113,8 +113,8 @@ module.exports = { this.errorMatcher.on('error', this.buildView.errorMessage.bind(this.buildView, 'Error matching failed!')); - this.errorMatcher.on('scroll', function(marker) { - this.buildView.scrollTo(marker); + this.errorMatcher.on('scroll', function(type, id) { + this.buildView.scrollTo(type, id); }.bind(this)); this.errorMatcher.on('replace', function(text) { diff --git a/lib/error-matcher.js b/lib/error-matcher.js index ad1abb46..22f0b74a 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -23,16 +23,17 @@ module.exports = (function () { util.inherits(ErrorMatcher, EventEmitter); ErrorMatcher.prototype._goto = function () { - var file = this.cwd + path.sep + this.currentMatch[0].file; - if (!this.currentMatch[0].file) { - file = this.currentMatch[0].absFile; + var match = this.currentMatch[0]; + var file = this.cwd + path.sep + match.file; + if (!match.file) { + file = match.absFile; } if (!file) { return this.emit('error', 'Did not match any file. Don\'t know what to open.'); } - var row = this.currentMatch[0].line ? this.currentMatch[0].line - 1 : 0; /* Because atom is zero-based */ - var col = this.currentMatch[0].col ? this.currentMatch[0].col - 1 : 0; /* Because atom is zero-based */ + var row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ + var col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ fs.exists(file, function (exists) { if (!exists) { @@ -42,7 +43,7 @@ module.exports = (function () { initialLine: row, initialColumn: col }); - this.emit('scroll', this.currentMatch[0].marker); + this.emit('scroll', match.type, match.id); this.currentMatch.push(this.currentMatch.shift()); }.bind(this)); @@ -50,15 +51,16 @@ module.exports = (function () { ErrorMatcher.prototype._parse = function () { this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match, i) { - match.marker = i; + match.type = 'error' + match.id = i; this.push(match); }, []); var output = this.output; var matchIndex; for (matchIndex in this.currentMatch) { var search = this.currentMatch[matchIndex][0]; - var replace = '' + this.currentMatch[matchIndex][0] + ''; - output = XRegExp.replace(output, search, replace); + var replace = '$&'; + output = XRegExp.replace(output, search, replace, 'one'); } this.emit('replace', output); return this.currentMatch.length; From c81374d9465cb5260591ebc88cf3559061bc8329 Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Sun, 7 Jun 2015 01:14:50 +0200 Subject: [PATCH 065/495] Fix copy and paste error in test --- spec/build-error-match-spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 47127251..dddf4730 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -22,6 +22,7 @@ describe('Build', function() { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); + atom.config.set('build.scrollOnError', false); jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); @@ -293,7 +294,7 @@ describe('Build', function() { expect(bufferPosition.column).toEqual(7); }); - atom.config.set('build.scrollOnError', true); + atom.config.set('build.scrollOnError', false); }); }); }); From 1c1df64d2773d074ad61b11f288003541f3d027c Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Sun, 7 Jun 2015 01:48:29 +0200 Subject: [PATCH 066/495] Remove wrong and uneccessary line --- spec/build-error-match-spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index dddf4730..f98b342e 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -293,8 +293,6 @@ describe('Build', function() { expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); }); - - atom.config.set('build.scrollOnError', false); }); }); }); From 9c2ad60c306d7484b765c149e4cabec2fd614345 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 7 Jun 2015 16:14:51 +0200 Subject: [PATCH 067/495] Prepare 0.37.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d2aeb5c..aea0f8bb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.36.1", + "version": "0.37.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 30ea697b8df19035455d772afcb835f1a4032a77 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 7 Jun 2015 16:24:46 +0200 Subject: [PATCH 068/495] SaveConfirmView: Only have one at a time If triggering the build multiple times without cancelling or confirming the save/build view, it will add additional views on top of the other. This makes sure we only have one view at a time. Fixes #85 --- lib/build.js | 4 ++++ spec/build-confirm-spec.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/build.js b/lib/build.js index c9e483c0..1c1827f3 100644 --- a/lib/build.js +++ b/lib/build.js @@ -363,6 +363,10 @@ module.exports = { return saveAndContinue(true); } + if (this.saveConfirmView) { + this.saveConfirmView.destroy(); + } + this.saveConfirmView = new SaveConfirmView(); this.saveConfirmView.show(saveAndContinue, cancelcb); }, diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 83d2be35..3aa32534 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -224,4 +224,35 @@ describe('Build', function() { }); }); + describe('when build is triggered without answering confirm dialog', function () { + it('should only keep at maximum 1 dialog open', function () { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + + waitsForPromise(function() { + return atom.workspace.open('Makefile'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + editor.insertText('hello kansas'); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build-confirm'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waits(200); // Everything is the same so we can't know when second build:trigger has been handled + + runs(function () { + expect(workspaceElement.querySelectorAll('.build-confirm').length).toEqual(1); + }); + }); + }); }); From 9c956a91c3b79eda2dd2080f3e275d13423e155f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 7 Jun 2015 16:29:55 +0200 Subject: [PATCH 069/495] package.json: Updated keywords --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aea0f8bb..f83dc317 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,6 @@ "compile", "gulp", "make", - "process" + "productivity" ] } From 6fbbd3fd8ecf5ad4e55a93b7c3b7bf612f0477e0 Mon Sep 17 00:00:00 2001 From: Lucas Keune Date: Sun, 7 Jun 2015 21:05:52 +0200 Subject: [PATCH 070/495] Don't use innerHTML directly --- lib/build-view.js | 6 +++--- lib/build.js | 2 +- lib/error-matcher.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 879ac6ae..c586dde1 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -192,12 +192,12 @@ module.exports = (function() { BuildView.prototype.replace = function(text) { this.output.empty(); - this.output.append(text); + this.output.append('
  • ' + (this.a2h.toHtml(text)) + '
  • '); + this.output.scrollTop(this.output[0].scrollHeight); }; BuildView.prototype.scrollTo = function(type, id) { - var interim = this.output.find('.' + type + '#' + id); - var position = interim.position(); + var position = this.output.find('.' + type + '#' + id).position(); if (position) { this.output.scrollTop(position.top + this.output.scrollTop()); } diff --git a/lib/build.js b/lib/build.js index 72996d6d..6f6bfdb3 100644 --- a/lib/build.js +++ b/lib/build.js @@ -308,7 +308,7 @@ module.exports = { }.bind(this), 1000); } else { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.context.innerHTML); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 22f0b74a..5053ef3e 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -51,7 +51,7 @@ module.exports = (function () { ErrorMatcher.prototype._parse = function () { this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match, i) { - match.type = 'error' + match.type = 'error'; match.id = i; this.push(match); }, []); From 9bde097d8eb2890fc57bdf0e66eed65f8f468c75 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 10 Jun 2015 21:12:37 +0200 Subject: [PATCH 071/495] Use Atom notification methods Atom has build in methodology for notifying the user. Using these wont intervene with whatever is in the build panel (which may still be relevant to the user, if e.g. an error match fails). Fixes #95 --- lib/build-view.js | 8 -------- lib/build.js | 10 ++++++---- spec/build-error-match-spec.js | 7 +++++-- spec/build-spec.js | 11 ++++++----- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 18badf2e..70805c76 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -176,14 +176,6 @@ module.exports = (function() { this.title.text('Aborted!'); }; - BuildView.prototype.errorMessage = function(title, message) { - this.reset(); - this.title.addClass('error'); - this.title.text(title); - this.append(message); - this.attach(); - }; - BuildView.prototype.append = function(line) { line = _.escape(line.toString()); this.output.append('
  • ' + (this.a2h.toHtml(line)) + '
  • '); diff --git a/lib/build.js b/lib/build.js index 1c1827f3..76a8d889 100644 --- a/lib/build.js +++ b/lib/build.js @@ -118,7 +118,9 @@ module.exports = { }); }); - this.errorMatcher.on('error', this.buildView.errorMessage.bind(this.buildView, 'Error matching failed!')); + this.errorMatcher.on('error', function (message) { + atom.notifications.addError('Error matching failed!', { detail: message }); + }); }, deactivate: function() { @@ -262,7 +264,7 @@ module.exports = { GoogleAnalytics.sendEvent('build', 'triggered'); if (!this.cmd.exec) { - this.buildView.errorMessage('Invalid build file.', 'No executable command specified.'); + atom.notifications.addError('Invalid build file.', { detail: 'No executable command specified.' }); return; } @@ -321,9 +323,9 @@ module.exports = { }).catch(NoToolError, function (error) { /* Maybe we should show the build-panel with an error message here? */ }).catch(SyntaxError, function (error) { - this.buildView.errorMessage('You have a syntax error in your build file.', error.message); + atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + error.message }); }).catch(function (error) { - this.buildView.errorMessage('Ooops. Something went wrong.', error.message + (error.stack ? '\n' + error.stack : '')); + atom.notifications.addError('Ooops. Something went wrong.', { detail: error.message + (error.stack ? '\n' + error.stack : '') }); }); }, diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index f98b342e..d0c87b0d 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -23,6 +23,7 @@ describe('Build', function() { atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); atom.config.set('build.scrollOnError', false); + atom.notifications.clear(); jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); @@ -86,11 +87,13 @@ describe('Build', function() { }); waitsFor(function() { - return workspaceElement.querySelector('.build .title').textContent === 'Error matching failed!'; + return atom.notifications.getNotifications().length > 0; }); runs(function() { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Matched file does not exist: .+black-hole/); + var notification = atom.notifications.getNotifications()[0]; + expect(notification.getType()).toEqual('error'); + expect(notification.getMessage()).toEqual('Error matching failed!'); }); }); diff --git a/spec/build-spec.js b/spec/build-spec.js index 49efd71e..291cc599 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -33,6 +33,7 @@ describe('Build', function() { atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); atom.config.set('build.stealFocus', true); + atom.notifications.clear(); workspaceElement = atom.views.getView(atom.workspace); jasmine.attachToDOM(workspaceElement); @@ -381,14 +382,14 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('error'); + return atom.notifications.getNotifications().length > 0; }); runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Unexpected token t/); - expect(workspaceElement.querySelector('.build .title').textContent).toBe('You have a syntax error in your build file.'); + var notification = atom.notifications.getNotifications()[0]; + expect(notification.getType()).toEqual('error'); + expect(notification.getMessage()).toEqual('Invalid build file.'); + expect(notification.options.detail).toMatch(/Unexpected token t/); }); }); From 4ede9fd9d81f4418a0672f429cb907abaefc32ce Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 10 Jun 2015 21:12:47 +0200 Subject: [PATCH 072/495] Specs: Detailed top-level describes For better spec output, detail which group a spec belongs to. --- spec/build-confirm-spec.js | 2 +- spec/build-error-match-spec.js | 2 +- spec/build-targets-spec.js | 2 +- spec/build-visible-spec.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 3aa32534..9ba07e61 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -2,7 +2,7 @@ var _ = require('lodash'); var fs = require('fs-extra'); var temp = require('temp'); -describe('Build', function() { +describe('Confirm', function() { 'use strict'; var goodMakefile = __dirname + '/fixture/Makefile.good'; diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index d0c87b0d..52fa3826 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,7 +1,7 @@ var fs = require('fs-extra'); var temp = require('temp'); -describe('Build', function() { +describe('Error Match', function() { 'use strict'; var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 19dfac44..57ca7f9e 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -4,7 +4,7 @@ var fs = Promise.promisifyAll(require('fs-extra')); var temp = Promise.promisifyAll(require('temp')); var specHelpers = require('./spec-helpers'); -describe('Build', function() { +describe('Target', function() { 'use strict'; var directory = null; diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index ab468975..68ae3d66 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -1,5 +1,5 @@ -describe('Build', function() { +describe('Visible', function() { 'use strict'; var workspaceElement = null; From 49c1124d4b53b34745d6b465f116b2242f735c65 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 10 Jun 2015 21:39:45 +0200 Subject: [PATCH 073/495] Do not emit unforseen errors to user If a child process has terminated or the kill signal was not delivered properly for some reason, swallow the error rather than throwing it in the users face. Fixes #78 --- lib/build.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 76a8d889..12559a24 100644 --- a/lib/build.js +++ b/lib/build.js @@ -337,7 +337,13 @@ module.exports = { cb(); } }.bind(this)); - this.child.kill(); + + try { + this.child.kill(); + } catch (e) { + /* Something may have happened to the child (e.g. terminated by itself). Ignore this. */ + } + this.child.killed = true; }, From f650f70ae78d8fed08d86054609852230290fa8f Mon Sep 17 00:00:00 2001 From: Jan Niklas Hasse Date: Sun, 14 Jun 2015 16:16:52 +0200 Subject: [PATCH 074/495] Search all panes when opening a matched file --- lib/error-matcher.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 335cdb7e..3779f94a 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -40,7 +40,8 @@ module.exports = (function () { } atom.workspace.open(file, { initialLine: row, - initialColumn: col + initialColumn: col, + searchAllPanes: true }); this.currentMatch.push(this.currentMatch.shift()); }.bind(this)); From 0f4327dca0f230ccd0dfc50e51a1cb4dede758ac Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 15 Jun 2015 22:56:57 +0200 Subject: [PATCH 075/495] Error matcher: `file` now matches relative and absolute Using same matcher reduces complexity. There is no risk for ambiguity since it is easy to determine if a path is absolute or not. In fact, this exists in core nodejs. Fixes #94 --- README.md | 3 +-- lib/error-matcher.js | 18 +++++++++++++----- spec/build-error-match-spec.js | 4 ++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1548ca20..1c1b56b0 100644 --- a/README.md +++ b/README.md @@ -116,8 +116,7 @@ and has the syntax for named groups: `(? RE )` where `name` would be the n matched by the regular expression `RE`. The following named groups can be matched from the output: - * `file` - **[required if not `absFile` is set]** the file to open. `(? RE)`. - * `absFile` - **[required if not `file` is set]** the absolute path to file. `(? RE)`. + * `file` - **[required]** the file to open. May be relative `cwd` or absolute. `(? RE)`. * `line` - **[optional]** the line the error resides on. `(? RE)`. * `col` - **[optional]** the column the error resides on. `(? RE)`. diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 3779f94a..6d0aaafa 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -23,17 +23,26 @@ module.exports = (function () { util.inherits(ErrorMatcher, EventEmitter); ErrorMatcher.prototype._goto = function () { - var file = this.cwd + path.sep + this.currentMatch[0].file; - if (!this.currentMatch[0].file) { - file = this.currentMatch[0].absFile; + if (this.currentMatch[0].absFile) { + atom.notifications.addWarning('`absFile` is deprecated.', { + detail: 'You should name your match `file` only. It handles both relative and absolute paths.' + }); } - if (!file) { + + if (!this.currentMatch[0].file && !this.currentMatch[0].absFile) { return this.emit('error', 'Did not match any file. Don\'t know what to open.'); } + var file = this.currentMatch[0].file ? this.currentMatch[0].file : this.currentMatch[0].absFile; + if (!path.isAbsolute(file)) { + file = this.cwd + path.sep + file; + } + var row = this.currentMatch[0].line ? this.currentMatch[0].line - 1 : 0; /* Because atom is zero-based */ var col = this.currentMatch[0].col ? this.currentMatch[0].col - 1 : 0; /* Because atom is zero-based */ + this.currentMatch.push(this.currentMatch.shift()); + fs.exists(file, function (exists) { if (!exists) { return this.emit('error', 'Matched file does not exist: ' + file); @@ -43,7 +52,6 @@ module.exports = (function () { initialColumn: col, searchAllPanes: true }); - this.currentMatch.push(this.currentMatch.shift()); }.bind(this)); }; diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 52fa3826..00430a15 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -246,10 +246,10 @@ describe('Error Match', function() { }); }); - it('should open the absolute file if absFile is set', function () { + it('should open the the file even if tool gives absolute path', function () { var atomBuild = { cmd: 'echo __' + directory + '.atom-build.json__ && return 1', - errorMatch: '__(?.+)__' + errorMatch: '__(?.+)__' }; fs.writeFileSync(directory + '.atom-build.json', JSON.stringify(atomBuild)); atom.commands.dispatch(workspaceElement, 'build:trigger'); From 89ccb20f041bd08131581cc6a42135bd9d759bb2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 15 Jun 2015 23:06:57 +0200 Subject: [PATCH 076/495] Prepare 0.38.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f83dc317..d46bdf7e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.37.0", + "version": "0.38.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 9edac2b2ef5dd76f621cd684f724eb0cfcc11fea Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 16 Jun 2015 21:44:23 +0200 Subject: [PATCH 077/495] Build: Show error if no build tool exists Give informative error if build is attempted but nothing exists to build the project. --- lib/build.js | 2 +- spec/build-spec.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 12559a24..10d88c66 100644 --- a/lib/build.js +++ b/lib/build.js @@ -321,7 +321,7 @@ module.exports = { this.buildView.buildStarted(); this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); }).catch(NoToolError, function (error) { - /* Maybe we should show the build-panel with an error message here? */ + atom.notifications.addError('No eligible build tool.', { detail: 'No tools available to build your project. Perhaps you didn\'t create .atom-build.json?' }); }).catch(SyntaxError, function (error) { atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + error.message }); }).catch(function (error) { diff --git a/spec/build-spec.js b/spec/build-spec.js index 291cc599..f2a8134d 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -773,4 +773,21 @@ describe('Build', function() { }); }); }); + + describe('when no build tools are available', function () { + it('should show an error', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return atom.notifications.getNotifications().length > 0; + }); + + runs(function() { + var notification = atom.notifications.getNotifications()[0]; + expect(notification.getType()).toEqual('error'); + expect(notification.getMessage()).toEqual('No eligible build tool.'); + }); + }); + }); }); From 336f2fcde0cea5be47651fcebd43eded2b9d0d8c Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 23 Jun 2015 13:45:14 +0200 Subject: [PATCH 078/495] BuildView: Option to keep build panel hidden If there are other means for viewing build output (e.g. by tailing a log in a terminal) then there's no need to show the build panel. Fixes #105 --- lib/build-view.js | 11 ++- lib/build.js | 2 +- spec/build-spec.js | 29 -------- spec/build-visible-spec.js | 140 ++++++++++++++++++++++++++++++++++--- 4 files changed, 141 insertions(+), 41 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 70805c76..0c991662 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -49,8 +49,12 @@ module.exports = (function() { }; BuildView.prototype.attach = function(force) { - if (!force && 'Show on Error' === atom.config.get('build.panelVisibility')) { - return; + if (!force) { + switch (atom.config.get('build.panelVisibility')) { + case 'Hidden': + case 'Show on Error': + return; + } } if (this.panel) { @@ -159,7 +163,8 @@ module.exports = (function() { BuildView.prototype.buildFinished = function(success) { if (!success) { - this.attach(true); + var force = (atom.config.get('build.panelVisibility') === 'Show on Error'); + this.attach(force); } this.title.text(success ? 'Build finished.' : 'Build failed.'); this.title.addClass(success ? 'success' : 'error'); diff --git a/lib/build.js b/lib/build.js index 10d88c66..931f2a9a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -30,7 +30,7 @@ module.exports = { description: 'Set when the build panel should be visible.', type: 'string', default: 'Toggle', - enum: [ 'Toggle', 'Keep Visible', 'Show on Error' ], + enum: [ 'Toggle', 'Keep Visible', 'Show on Error', 'Hidden' ], order: 1 }, buildOnSave: { diff --git a/spec/build-spec.js b/spec/build-spec.js index f2a8134d..3b9a1d95 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -55,35 +55,6 @@ describe('Build', function() { fs.removeAsync(directory); }); - describe('when panel visibility is set to show on error', function() { - it('should only show an the build panel if a build fails', function () { - atom.config.set('build.panelVisibility', 'Show on Error'); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - /* Give it some reasonable time to show itself if there is a bug */ - waits(1000); - - runs(function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - }); - - runs(function () { - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(badMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); - }); - }); - }); - describe('when package is activated', function() { it('should not show build window if panelVisibility is Toggle ', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index 68ae3d66..8ee73cfb 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -1,11 +1,26 @@ +var Promise = require('bluebird'); +var fs = Promise.promisifyAll(require('fs-extra')); +var temp = Promise.promisifyAll(require('temp')); describe('Visible', function() { 'use strict'; + var directory = null; var workspaceElement = null; + temp.track(); + beforeEach(function() { - atom.config.set('build.panelVisibility', 'Keep Visible'); + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + atom.config.set('build.stealFocus', true); + atom.notifications.clear(); + + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); runs(function() { workspaceElement = atom.views.getView(atom.workspace); @@ -13,23 +28,132 @@ describe('Visible', function() { }); waitsForPromise(function() { - return atom.packages.activatePackage('build'); + return temp.mkdirAsync({ prefix: 'atom-build-spec-' }).then(function (dir) { + return fs.realpathAsync(dir); + }).then(function (dir) { + directory = dir + '/'; + atom.project.setPaths([ directory ]); + }); }); }); - describe('when package is activated', function() { + describe('when package is activated with panel visibility set to Keep Visible', function() { + beforeEach(function () { + atom.config.set('build.panelVisibility', 'Keep Visible'); + waitsForPromise(function () { + return atom.packages.activatePackage('build'); + }); + }); + it('should show build window', function() { expect(workspaceElement.querySelector('.build')).toExist(); }); }); - describe('when build panel is toggled and it is visible', function() { - it('should hide the build panel', function() { - expect(workspaceElement.querySelector('.build')).toExist(); + describe('when package is activated with panel visibility set to Toggle', function () { + beforeEach(function () { + atom.config.set('build.panelVisibility', 'Toggle'); + waitsForPromise(function () { + return atom.packages.activatePackage('build'); + }); + }); + + describe('when build panel is toggled and it is visible', function() { + beforeEach(function () { + atom.config.set('build.panelVisibility', 'Keep Visible'); + waitsForPromise(function () { + return atom.packages.activatePackage('build'); + }); + }); + + it('should hide the build panel', function() { + expect(workspaceElement.querySelector('.build')).toExist(); + + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + + expect(workspaceElement.querySelector('.build')).not.toExist(); + }); + }); + + describe('when panel visibility is set to Show on Error', function() { + it('should only show an the build panel if a build fails', function () { + atom.config.set('build.panelVisibility', 'Show on Error'); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.good')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + /* Give it some reasonable time to show itself if there is a bug */ + waits(200); + + runs(function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + }); + + runs(function () { + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.bad')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); + }); + }); + }); + + describe('when panel visibility is set to Hidden', function() { + it('should not show the build panel if build succeeeds', function () { + atom.config.set('build.panelVisibility', 'Hidden'); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.good')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + /* Give it some reasonable time to show itself if there is a bug */ + waits(200); + + runs(function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + }); + }); + + it('should not show the build panel if build fails', function () { + atom.config.set('build.panelVisibility', 'Hidden'); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.bad')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + /* Give it some reasonable time to show itself if there is a bug */ + waits(200); + + runs(function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + }); + }); + + it('should show the build panel if it is toggled', function () { + atom.config.set('build.panelVisibility', 'Hidden'); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.good')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waits(200); // Let build finish. Since UI component is not visible yet, there's nothing to poll. + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); - atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); - expect(workspaceElement.querySelector('.build')).not.toExist(); + runs(function() { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); + }); + }); }); }); }); From be6bbfee4aed8cc95fa3273ac8869e042602c93e Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 23 Jun 2015 19:52:51 +0200 Subject: [PATCH 079/495] Build: Handle when no project is open When no project is open, there is really nothing to build and atom will return empty projects array. Handle this case with a proper error message. Fixes #104 --- lib/build.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/build.js b/lib/build.js index 931f2a9a..fdc92a8c 100644 --- a/lib/build.js +++ b/lib/build.js @@ -14,14 +14,14 @@ var GoogleAnalytics = require('./google-analytics'); var ErrorMatcher = require('./error-matcher'); var tools = require('./tools'); -function NoToolError() { - this.message = 'No tool can provide any build configurations.'; - this.name = 'NoToolSelected'; - Error.captureStackTrace(this, NoToolError); +function BuildError(name, message) { + this.name = name; + this.message = message; + Error.captureStackTrace(this, BuildError); } -NoToolError.prototype = Object.create(Error.prototype); -NoToolError.prototype.constructor = NoToolError; +BuildError.prototype = Object.create(Error.prototype); +BuildError.prototype.constructor = BuildError; module.exports = { config: { @@ -137,6 +137,10 @@ module.exports = { var textEditor = atom.workspace.getActiveTextEditor(); if (!textEditor || !textEditor.getPath()) { /* default to building the first one if no editor is active */ + if (0 === atom.project.getPaths().length) { + return false; + } + return atom.project.getPaths()[0]; } else { /* otherwise, build the one in the root of the active editor */ @@ -176,6 +180,10 @@ module.exports = { }) .catch(function(err) { /* Unable to watch file. Updates to custom file will require manual refresh */ }) .then(function () { + if (!path) { + throw new BuildError('No active project', 'No project is active, don\'t know what to build...'); + } + return _.filter(tools, function (tool) { return tool.isEligable(path); }); @@ -189,7 +197,7 @@ module.exports = { .then(_.flatten) .then(function (settings) { if (0 === _.size(settings)) { - throw new NoToolError(); + throw new BuildError('No eligible build tool.', 'No tool can provide any build configurations.'); } prioritizedTarget = settings[0].name; @@ -220,7 +228,7 @@ module.exports = { var workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); - }).catch(NoToolError, function (error) { + }).catch(BuildError, function (error) { targetsView.setError(error.message); }).catch(function (error) { targetsView.setError(error.message); @@ -320,8 +328,8 @@ module.exports = { this.buildView.buildStarted(); this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); - }).catch(NoToolError, function (error) { - atom.notifications.addError('No eligible build tool.', { detail: 'No tools available to build your project. Perhaps you didn\'t create .atom-build.json?' }); + }).catch(BuildError, function (error) { + atom.notifications.addError(error.name, { detail: error.message }); }).catch(SyntaxError, function (error) { atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + error.message }); }).catch(function (error) { From c2f6e95c4945dee832a176f98610409127f3d60c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20=E2=80=9CFelds=E2=80=9D=20Liscia?= Date: Thu, 25 Jun 2015 16:05:39 -0300 Subject: [PATCH 080/495] Enable the use of coffee configuration for Gulp. --- lib/tools/gulp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 261e6bdf..f9b4f121 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -12,7 +12,7 @@ var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'gulp'; module.exports.isEligable = function (cwd) { - return fs.existsSync(path.join(cwd, 'gulpfile.js')); + return fs.existsSync(path.join(cwd, 'gulpfile.js')) || fs.existsSync(path.join(cwd, 'gulpfile.coffee')); }; module.exports.settings = function (cwd) { From 933a377f5b3ce5b9874c93bba8e0b07a298a0148 Mon Sep 17 00:00:00 2001 From: Colin Kiegel Date: Sat, 27 Jun 2015 17:35:24 +0200 Subject: [PATCH 081/495] Update Cargo.js support for additional targets (cargo/rust) --- lib/tools/Cargo.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js index 1c696eda..2311b6bd 100644 --- a/lib/tools/Cargo.js +++ b/lib/tools/Cargo.js @@ -10,10 +10,24 @@ module.exports.isEligable = function (path) { module.exports.settings = function (path) { return [ { - name: 'Cargo: default', + name: 'Cargo: build', exec: 'cargo', args: [ 'build' ], sh: false, errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' - } ]; + }, + { + name: 'Cargo: test', + exec: 'cargo', + args: [ 'test' ], + sh: false, + errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' + }, + { + name: 'Cargo: run', + exec: 'cargo', + args: [ 'run' ], + sh: false, + errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' + }]; }; From 9e71e0dd0bebb23ae65737af98511cd0388ef45e Mon Sep 17 00:00:00 2001 From: Colin Kiegel Date: Sun, 28 Jun 2015 10:36:58 +0200 Subject: [PATCH 082/495] Update Cargo.js Update: I changed the regexp, because it didn't work for me. I found out that both '^' and [^.....] are not being interpreted as expected. --- lib/tools/Cargo.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js index 2311b6bd..4492eb18 100644 --- a/lib/tools/Cargo.js +++ b/lib/tools/Cargo.js @@ -14,20 +14,20 @@ module.exports.settings = function (path) { exec: 'cargo', args: [ 'build' ], sh: false, - errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' + errorMatch: '(?.+.rs):(?\\d+):(?\\d+):' }, { name: 'Cargo: test', exec: 'cargo', args: [ 'test' ], sh: false, - errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' + errorMatch: '(?.+.rs):(?\\d+):(?\\d+):' }, { name: 'Cargo: run', exec: 'cargo', args: [ 'run' ], sh: false, - errorMatch: '^(?[^\\.]+.rs):(?\\d+):(?\\d+):' + errorMatch: '(?.+.rs):(?\\d+):(?\\d+):' }]; }; From 392d556f841ba2601be640e6059abbda7c3163cf Mon Sep 17 00:00:00 2001 From: Koen Date: Sun, 28 Jun 2015 12:21:50 +0200 Subject: [PATCH 083/495] don't attach view on package activation --- lib/build-view.js | 10 +++++----- spec/build-spec.js | 2 +- spec/build-visible-spec.js | 9 +++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 0c991662..22f61f68 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -18,7 +18,7 @@ module.exports = (function() { this.titleLoopIndex = 0; this.a2h = new Convert(); this.monocle = false; - this.attach(); + // this.attach(); atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this)); @@ -95,10 +95,10 @@ module.exports = (function() { this.detach(); } break; - - case 'Keep Visible': - this.attach(); - break; + // + // case 'Keep Visible': + // this.attach(); + // break; } }; diff --git a/spec/build-spec.js b/spec/build-spec.js index 3b9a1d95..09de842c 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -65,7 +65,7 @@ describe('Build', function() { it('should not leave multiple panels behind', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); - atom.config.set('build.panelVisibility', 'Keep Visible'); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); atom.commands.dispatch(workspaceElement, 'build:trigger'); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index 8ee73cfb..fba14285 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -45,8 +45,8 @@ describe('Visible', function() { }); }); - it('should show build window', function() { - expect(workspaceElement.querySelector('.build')).toExist(); + it('should not show build window', function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); @@ -60,10 +60,7 @@ describe('Visible', function() { describe('when build panel is toggled and it is visible', function() { beforeEach(function () { - atom.config.set('build.panelVisibility', 'Keep Visible'); - waitsForPromise(function () { - return atom.packages.activatePackage('build'); - }); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); it('should hide the build panel', function() { From 232e6bfe6a79a2ace2485d15caf780a73ae0d35e Mon Sep 17 00:00:00 2001 From: Koen Lageveen Date: Sun, 28 Jun 2015 12:27:06 +0200 Subject: [PATCH 084/495] remove comments --- lib/build-view.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 22f61f68..b1889ce6 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -18,7 +18,6 @@ module.exports = (function() { this.titleLoopIndex = 0; this.a2h = new Convert(); this.monocle = false; - // this.attach(); atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this)); @@ -95,10 +94,6 @@ module.exports = (function() { this.detach(); } break; - // - // case 'Keep Visible': - // this.attach(); - // break; } }; From fd349df35b8e35cab5e85568288a2706cffac3ba Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 29 Jun 2015 15:47:06 +0200 Subject: [PATCH 085/495] Prepare 0.39.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d46bdf7e..dd010347 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.38.0", + "version": "0.39.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 4e4a43878fddd1f606eb9db3ef45a3f7d6043365 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 1 Jul 2015 21:12:51 +0200 Subject: [PATCH 086/495] Skip error when building on save with no tool Because buildOnSave is a global configuration a user who prefers this will have it set. If said user just opens and save a random file, there will be a no tool build error. It is unlikely that the user wants to see this error when building on save without a build tool, so skip it. Fixes #102 --- lib/build.js | 25 +++++++++++++------------ spec/build-spec.js | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/lib/build.js b/lib/build.js index fdc92a8c..0fd0b7ad 100644 --- a/lib/build.js +++ b/lib/build.js @@ -97,7 +97,7 @@ module.exports = { this.stderr = new Buffer(0); this.errorMatcher = new ErrorMatcher(); - atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this)); + atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this, 'trigger')); atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this)); atom.commands.add('atom-workspace', 'build:confirm', function() { @@ -112,11 +112,10 @@ module.exports = { atom.workspace.observeTextEditors(function(editor) { editor.onDidSave(function(event) { if (atom.config.get('build.buildOnSave')) { - var workspaceElement = atom.views.getView(atom.workspace); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + this.build('save'); } - }); - }); + }.bind(this)); + }.bind(this)); this.errorMatcher.on('error', function (message) { atom.notifications.addError('Error matching failed!', { detail: message }); @@ -258,7 +257,7 @@ module.exports = { return value; }, - startNewBuild: function() { + startNewBuild: function(source) { this.cmd = {}; this.match = []; @@ -329,6 +328,11 @@ module.exports = { this.buildView.buildStarted(); this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); }).catch(BuildError, function (error) { + if (source === 'save') { + // If there is no eligible build tool, and cause of build was a save, stay quiet. + return; + } + atom.notifications.addError(error.name, { detail: error.message }); }).catch(SyntaxError, function (error) { atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + error.message }); @@ -355,15 +359,12 @@ module.exports = { this.child.killed = true; }, - build: function() { + build: function(source) { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), function() { - if (this.child) { - this.abort(this.startNewBuild.bind(this)); - } else { - this.startNewBuild(); - } + var next = this.startNewBuild.bind(this, source); + this.child ? this.abort(next) : next(); }.bind(this)); }, diff --git a/spec/build-spec.js b/spec/build-spec.js index 09de842c..a48b272d 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -669,6 +669,25 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); + + it('should not attempt to build if buildOnSave is true and no build tool exists', function () { + atom.config.set('build.buildOnSave', true); + + waitsForPromise(function() { + return atom.workspace.open('dummy'); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + editor.save(); + }); + + waits(200); + + runs(function() { + expect(atom.notifications.getNotifications().length).toEqual(0); + }); + }); }); describe('when multiple project roots are open', function () { From a7ddcc9eecd74d9146d271ec96f11790f82f213a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 1 Jul 2015 21:34:56 +0200 Subject: [PATCH 087/495] BuildView: set configured height on attach Regression introduced in 392d556. Set the configured height percent when attaching. Fixes #118 --- lib/build-view.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index b1889ce6..fdf279a2 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -61,6 +61,7 @@ module.exports = (function() { } this.panel = atom.workspace.addBottomPanel({ item: this }); this.height = this.output.offset().top + this.output.height(); + this.heightFromConfig(); }; BuildView.prototype.detach = function(force) { @@ -78,7 +79,7 @@ module.exports = (function() { return !!this.panel; }; - BuildView.prototype.heightFromConfig = function(val) { + BuildView.prototype.heightFromConfig = function() { if (this.monocle) { this.setHeightPercent(atom.config.get('build.monocleHeight')); } else { From 2418bda635912d50c204758b0e1d9eda4fbe2b71 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 2 Jul 2015 09:55:03 +0200 Subject: [PATCH 088/495] Prepare 0.40.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd010347..8417c9d9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.39.0", + "version": "0.40.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 39376e4dfcfae3123ce3198691cae9db108bf39d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 6 Jul 2015 20:55:29 +0200 Subject: [PATCH 089/495] NPM and APM scripts are build targets Scripts defined in the package.json file now show up as build targets. Fixes #125 --- lib/build.js | 2 +- lib/tools/npm_apm.js | 16 +++++++++--- spec/build-spec.js | 47 ++++++++++++++++++++++++++++++++-- spec/fixture/package.json.atom | 3 +++ spec/fixture/package.json.node | 3 +++ 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/lib/build.js b/lib/build.js index 0fd0b7ad..961c6421 100644 --- a/lib/build.js +++ b/lib/build.js @@ -398,7 +398,7 @@ module.exports = { clearTimeout(this.finishedTimer); if (this.child) { - if (this.child.killed){ + if (this.child.killed) { // This child has been killed, but hasn't terminated. Hide it from user. this.child.removeAllListeners(); this.child = null; diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index f671201e..1852550f 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -26,10 +26,20 @@ module.exports.settings = function (cwd) { var pkg = require(realPackage); var executableExtension = /^win/.test(process.platform) ? '.cmd' : ''; - return { - name: pkg.engines.node ? 'npm' : 'apm', + var config = [ { + name: pkg.engines.node ? 'npm: default' : 'apm: default', exec: (pkg.engines.node ? 'npm' : 'apm') + executableExtension, args: [ '--color=always', 'install' ], sh: false - }; + } ]; + + for (var script in pkg.scripts) { + config.push({ + name: 'npm: ' + script, + exec: 'npm', + args: [ '--color=always', 'run', script ], + sh: false + }); + } + return config; }; diff --git a/spec/build-spec.js b/spec/build-spec.js index a48b272d..7a96a6e3 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,11 +1,12 @@ +'use strict'; + +var _ = require('lodash'); var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs-extra')); var temp = Promise.promisifyAll(require('temp')); var specHelpers = require('./spec-helpers'); describe('Build', function() { - 'use strict'; - var goodMakefile = __dirname + '/fixture/Makefile.good'; var badMakefile = __dirname + '/fixture/Makefile.bad'; var longMakefile = __dirname + '/fixture/Makefile.long'; @@ -258,6 +259,48 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); + + it('should list scripts as build targets', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + console.log('active targets'); + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'npm: default', 'npm: custom script' ]); + }); + }); + + it('should list package.json files with engine atom scripts as run by NPM', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile)); + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:select-active-target'); + }); + + waitsFor(function () { + console.log('active targets'); + return workspaceElement.querySelector('.select-list li.build-target'); + }); + + runs(function () { + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { + return el.textContent; + }); + expect(targets).toEqual([ 'apm: default', 'npm: custom script' ]); + }); + }); }); describe('when custom .atom-build.json is available', function() { diff --git a/spec/fixture/package.json.atom b/spec/fixture/package.json.atom index e381d02b..05517d79 100644 --- a/spec/fixture/package.json.atom +++ b/spec/fixture/package.json.atom @@ -4,5 +4,8 @@ "private": true, "engines": { "atom": ">=0.50.0" + }, + "scripts": { + "custom script": "echo 'custom script'" } } diff --git a/spec/fixture/package.json.node b/spec/fixture/package.json.node index ba3fd6b1..ec03ae51 100644 --- a/spec/fixture/package.json.node +++ b/spec/fixture/package.json.node @@ -4,5 +4,8 @@ "private": true, "engines": { "node": "0.10.x" + }, + "scripts": { + "custom script": "echo 'custom script'" } } From 245933b52717353bd04e5cbad717f6a566b682f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Furkan=20Tunal=C4=B1?= Date: Thu, 9 Jul 2015 20:21:52 +0300 Subject: [PATCH 090/495] Enable the use of babel configuration for Gulp. --- lib/tools/gulp.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index f9b4f121..94a1d3f3 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -12,7 +12,9 @@ var originalNodePath = process.env.NODE_PATH; module.exports.niceName = 'gulp'; module.exports.isEligable = function (cwd) { - return fs.existsSync(path.join(cwd, 'gulpfile.js')) || fs.existsSync(path.join(cwd, 'gulpfile.coffee')); + return fs.existsSync(path.join(cwd, 'gulpfile.js')) || + fs.existsSync(path.join(cwd, 'gulpfile.coffee')) || + fs.existsSync(path.join(cwd, 'gulpfile.babel.js')); }; module.exports.settings = function (cwd) { From 10ba88365790ec814b6c1a4d4d2a486c27dc7f78 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 10 Jul 2015 11:01:24 +0200 Subject: [PATCH 091/495] Spec: Remove accidential console.log --- spec/build-spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/build-spec.js b/spec/build-spec.js index 7a96a6e3..4e8ab4fe 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -269,7 +269,6 @@ describe('Build', function() { }); waitsFor(function () { - console.log('active targets'); return workspaceElement.querySelector('.select-list li.build-target'); }); @@ -290,7 +289,6 @@ describe('Build', function() { }); waitsFor(function () { - console.log('active targets'); return workspaceElement.querySelector('.select-list li.build-target'); }); From cf32c9ca04cd5e03c3e9f687674338975f6c7068 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 10 Jul 2015 17:47:44 +0200 Subject: [PATCH 092/495] Register keymaps for builds .atom-build.json now support keymaps for build targets. This allows for easy assigning a key combination to a specific build target and trigger it swiftly. Fixes #120 --- README.md | 2 + lib/build.js | 33 +++++- lib/tools/atom-build.js | 3 +- spec/build-keymap-spec.js | 225 ++++++++++++++++++++++++++++++++++++++ spec/spec-helpers.js | 35 ++++++ 5 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 spec/build-keymap-spec.js diff --git a/README.md b/README.md index 1c1b56b0..057dd764 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ exactly what to execute. Create a file named `.atom-build.json` in your project ... }, "errorMatch": "^regexp$", + "keymap": "", "targets": { "": { "cmd": "", @@ -78,6 +79,7 @@ systems). * `cwd` - **[optional]** The working directory for the command. E.g. what `.` resolves to. * `env` - **[optional]** An array of environment variables and their values to set * `errorMatch` - **[optional]** A regular expression to match output to a file, row and col. See [Error matching](#error-match) for details. + * `keymap` - **[optional]** A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. * `targets`- **[optional]** Additional targets which can be used to build variations of your project. ### Replacements diff --git a/lib/build.js b/lib/build.js index 961c6421..83a19fb9 100644 --- a/lib/build.js +++ b/lib/build.js @@ -120,6 +120,8 @@ module.exports = { this.errorMatcher.on('error', function (message) { atom.notifications.addError('Error matching failed!', { detail: message }); }); + + this.refreshTargets().catch(function (e) {}); }, deactivate: function() { @@ -210,6 +212,29 @@ module.exports = { /* Active target has been removed or not set. Set it to the highest prio target */ this.activeTarget = prioritizedTarget; } + + _.forEach(this.targets, function (target) { + target.dispose(); // Gets rid of keymaps and commands registered + }); + + _.forEach(targets, function (target, targetName) { + if (!target.keymap) { + target.dispose = _.noop; + return; + } + + GoogleAnalytics.sendEvent('keymap', 'registered', target.keymap); + var commandName = 'build:trigger:' + targetName; + var keymapSpec = { 'atom-workspace': {} }; + keymapSpec['atom-workspace'][target.keymap] = commandName; + var keymapDispose = atom.keymaps.add(targetName, keymapSpec); + var commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); + target.dispose = function () { + keymapDispose.dispose(); + commandDispose.dispose(); + }; + }.bind(this)); + return (this.targets = targets); }); }, @@ -257,7 +282,7 @@ module.exports = { return value; }, - startNewBuild: function(source) { + startNewBuild: function(source, targetName) { this.cmd = {}; this.match = []; @@ -267,7 +292,7 @@ module.exports = { return (this.activeTarget) ? this.targets : this.refreshTargets(); }) .then(function (targets) { - this.cmd = targets[this.activeTarget]; + this.cmd = targets[targetName ? targetName : this.activeTarget]; GoogleAnalytics.sendEvent('build', 'triggered'); if (!this.cmd.exec) { @@ -359,11 +384,11 @@ module.exports = { this.child.killed = true; }, - build: function(source) { + build: function(source, event) { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), function() { - var next = this.startNewBuild.bind(this, source); + var next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); this.child ? this.abort(next) : next(); }.bind(this)); }, diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index e266c185..014174e1 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -22,7 +22,8 @@ module.exports.settings = function (cwd) { args: build.args, cwd: build.cwd, sh: build.sh, - errorMatch: build.errorMatch + errorMatch: build.errorMatch, + keymap: build.keymap }; }; diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js new file mode 100644 index 00000000..61cbd96a --- /dev/null +++ b/spec/build-keymap-spec.js @@ -0,0 +1,225 @@ +var fs = require('fs-extra'); +var temp = require('temp'); +var specHelpers = require('./spec-helpers'); + +describe('Keymap', function() { + 'use strict'; + + var directory = null; + var workspaceElement = null; + + temp.track(); + + beforeEach(function() { + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + atom.project.setPaths([ directory ]); + + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + + runs(function() { + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + }); + + waitsForPromise(function() { + return atom.packages.activatePackage('build'); + }); + }); + + afterEach(function() { + fs.removeSync(directory); + }); + + describe('when custom keymap is defined in .atom-build.json', function () { + it('should trigger the build when that key combination is pressed', function () { + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + name: 'The default build', + cmd: 'echo default', + targets: { + 'keymapped build': { + cmd: 'echo keymapped', + keymap: 'ctrl-alt-k' + } + } + })); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); + + waitsFor(function() { + return !workspaceElement.querySelector('.build .title'); + }); + + runs(function () { + specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); + }); + }); + + it('should not changed the set active build', function () { + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + name: 'The default build', + cmd: 'echo default', + targets: { + 'keymapped build': { + cmd: 'echo keymapped', + keymap: 'ctrl-alt-k' + } + } + })); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); + + waitsFor(function() { + return !workspaceElement.querySelector('.build .title'); + }); + + runs(function () { + specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); + + waitsFor(function() { + return !workspaceElement.querySelector('.build .title'); + }); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); + }); + + it('should dispose keymap when reloading targets', function () { + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + name: 'The default build', + cmd: 'echo default', + targets: { + 'keymapped build': { + cmd: 'echo keymapped', + keymap: 'ctrl-alt-k' + } + } + })); + + runs(function () { + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); + + waitsFor(function() { + return !workspaceElement.querySelector('.build .title'); + }); + + runs(function () { + specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + name: 'The default build', + cmd: 'echo default', + targets: { + 'keymapped build': { + cmd: 'echo ctrl-x new file', + keymap: 'ctrl-x' + } + } + })); + }); + + waits(300); // .atom-build.json is reloaded automatically + + runs(function () { + specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); + }); + + waits(300); + + runs(function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + specHelpers.keydown('x', { ctrl: true, element: workspaceElement }); + }); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/ctrl-x new file/); + }); + }); + }); +}); diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js index c7301292..a47c92f1 100644 --- a/spec/spec-helpers.js +++ b/spec/spec-helpers.js @@ -35,5 +35,40 @@ module.exports = { return fs.symlinkAsync(realGulp, binGulp); }); }; + }, + + _dispatchKeyboardEvent: function (type, element, key, ctrl, alt, shift, meta) { + var charCode = key.charCodeAt(0); + var unicode = 'U+00' + charCode.toString(16).toUpperCase(); + var e = document.createEvent('KeyboardEvent'); + e.initKeyboardEvent(type, true, true, null, unicode, 0, ctrl, alt, shift, meta); + document.dispatchEvent(e); + }, + + keyboardEvent: function (key, opts) { + var element = opts.element || document.activeElement; + this._dispatchKeyboardEvent('keydown', element, key, true, true, false, false); + this._dispatchKeyboardEvent('keypress', element, key, true, true, false, false); + this._dispatchKeyboardEvent('keyup', element, key, true, true, false, false); + }, + + dispatchKeyboardEvent: function (target, type, eventArgs) { + var e = document.createEvent('KeyboardEvent'); + e.initKeyboardEvent.apply(e, [ type ].concat(eventArgs)); + if (e.keyCode === 0) { + Object.defineProperty(e, 'keyCode', { + get: function() { return undefined; } + }); + } + return target.dispatchEvent(e); + }, + + keydown: function (key, opt) { + var unicode = 'U+' + key.charCodeAt(0).toString(16); + var element = opt.element || document.activeElement; + var eventArgs = [ true, true, null, unicode, 0, opt.ctrl, opt.alt, opt.shift, opt.meta ]; + this.dispatchKeyboardEvent(element, 'keydown', eventArgs); + this.dispatchKeyboardEvent(element, 'keypress', eventArgs); + this.dispatchKeyboardEvent(element, 'keyup', eventArgs); } }; From 4a67f85e5a7445c165d3e441d7621273a0ae5dc0 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 10 Jul 2015 17:52:15 +0200 Subject: [PATCH 093/495] README: fixed typo, env is an object --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 057dd764..43d5777e 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ systems). * `args` - **[optional]** An array of arguments for the command * `sh` - **[optional]** If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. * `cwd` - **[optional]** The working directory for the command. E.g. what `.` resolves to. - * `env` - **[optional]** An array of environment variables and their values to set + * `env` - **[optional]** An object of environment variables and their values to set * `errorMatch` - **[optional]** A regular expression to match output to a file, row and col. See [Error matching](#error-match) for details. * `keymap` - **[optional]** A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. * `targets`- **[optional]** Additional targets which can be used to build variations of your project. From e1f17ca663693542c981a0a5916716048adafdd2 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 12 Jul 2015 20:59:21 +0200 Subject: [PATCH 094/495] fixed merge error --- lib/build.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index c1768974..a1d0f4e5 100644 --- a/lib/build.js +++ b/lib/build.js @@ -121,8 +121,6 @@ module.exports = { atom.notifications.addError('Error matching failed!', { detail: message }); }); - this.errorMatcher.on('error', this.buildView.errorMessage.bind(this.buildView, 'Error matching failed!')); - this.errorMatcher.on('scroll', function(type, id) { this.buildView.scrollTo(type, id); }.bind(this)); @@ -131,7 +129,7 @@ module.exports = { this.buildView.replace(text); }.bind(this)); - this.refreshTargets().catch(function(e) {}); + this.refreshTargets().catch(function(e) {}); }, deactivate: function() { From c63d5a73460ab2f0e638bdb0f7dfcb57383f152a Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 12 Jul 2015 21:20:47 +0200 Subject: [PATCH 095/495] fixed reinserting errors with < > --- lib/error-matcher.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 5bad9c68..cd69da5d 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -6,6 +6,7 @@ var XRegExp = require('xregexp').XRegExp; var GoogleAnalytics = require('./google-analytics'); var EventEmitter = require('events').EventEmitter; var util = require('util'); +var _ = require('lodash'); module.exports = (function () { @@ -23,17 +24,17 @@ module.exports = (function () { util.inherits(ErrorMatcher, EventEmitter); ErrorMatcher.prototype._goto = function () { - if (this.currentMatch[0].absFile) { + var match = this.currentMatch[0]; + if (match.absFile) { atom.notifications.addWarning('`absFile` is deprecated.', { detail: 'You should name your match `file` only. It handles both relative and absolute paths.' }); } - if (!this.currentMatch[0].file && !this.currentMatch[0].absFile) { + if (!match.file && !match.absFile) { return this.emit('error', 'Did not match any file. Don\'t know what to open.'); } - var match = this.currentMatch[0]; var file = match.file ? match.file : match.absFile; if (!path.isAbsolute(file)) { file = this.cwd + path.sep + file; @@ -67,8 +68,8 @@ module.exports = (function () { var matchIndex; for (matchIndex in this.currentMatch) { var search = this.currentMatch[matchIndex][0]; - var replace = '$&'; - output = XRegExp.replace(output, search, replace, 'one'); + var replace = '' + _.escape(search) + ''; + output = output.replace(search, replace); } this.emit('replace', output); return this.currentMatch.length; From 4af63036f3792ecae4ec307090f7e0ce4f96b60b Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 12 Jul 2015 22:52:00 +0200 Subject: [PATCH 096/495] added support for multiple regexes --- lib/build.js | 6 +++++- lib/error-matcher.js | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/build.js b/lib/build.js index a1d0f4e5..8da7eb29 100644 --- a/lib/build.js +++ b/lib/build.js @@ -349,7 +349,11 @@ module.exports = { }.bind(this), 1000); } else { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); + var errorMatch = t.errorMatch; + if(!(errorMatch instanceof Array)) { + errorMatch = [errorMatch]; + } + this.errorMatcher.set(errorMatch, this.replace(t.cwd), this.buildView.output.text()); if (atom.config.get('build.scrollOnError')) { this.errorMatcher.matchFirst(); } diff --git a/lib/error-matcher.js b/lib/error-matcher.js index cd69da5d..f7ba6c48 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -59,11 +59,17 @@ module.exports = (function () { }; ErrorMatcher.prototype._parse = function () { - this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match, i) { - match.type = 'error'; - match.id = i; - this.push(match); - }, []); + this.currentMatch = []; + var regexIndex; + console.log(this.regex); + for (regexIndex in this.regex) { + console.log(regexIndex, this.regex[regexIndex]); + XRegExp.forEach(this.output, this.regex[regexIndex], function (match, i) { + match.type = 'error'; + match.id = i; + this.push(match); + }, this.currentMatch); + } var output = this.output; var matchIndex; for (matchIndex in this.currentMatch) { @@ -76,7 +82,10 @@ module.exports = (function () { }; ErrorMatcher.prototype.set = function (regex, cwd, output) { - this.regex = XRegExp(regex); + this.regex = []; + for(var i in regex) { + this.regex.push(XRegExp(regex[i])); + } this.cwd = cwd; this.output = output; this.currentMatch = []; From c089e351a8161a386af383c94fc7d5d932ad9cd4 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 12 Jul 2015 22:56:14 +0200 Subject: [PATCH 097/495] escape EVERYTHING --- lib/error-matcher.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index cd69da5d..02f44ed6 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -64,11 +64,11 @@ module.exports = (function () { match.id = i; this.push(match); }, []); - var output = this.output; + var output = _.escape(this.output); var matchIndex; for (matchIndex in this.currentMatch) { - var search = this.currentMatch[matchIndex][0]; - var replace = '' + _.escape(search) + ''; + var search = _.escape(this.currentMatch[matchIndex][0]); + var replace = '$&'; output = output.replace(search, replace); } this.emit('replace', output); From 209beec75b460258e454443c064c5beab576c9fd Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 12 Jul 2015 23:21:03 +0200 Subject: [PATCH 098/495] fixed crash on invalid regex --- lib/error-matcher.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 6d0aaafa..50e7203e 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -63,7 +63,12 @@ module.exports = (function () { }; ErrorMatcher.prototype.set = function (regex, cwd, output) { - this.regex = XRegExp(regex); + try { + this.regex = XRegExp(regex); + } catch(err) { + this.regex = null; + return this.emit('error', 'Error parsing regex:\n' + err); + } this.cwd = cwd; this.output = output; this.currentMatch = []; From 62f9a0099796c5f35ed4c96942e7ca454820a359 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 13 Jul 2015 00:09:14 +0200 Subject: [PATCH 099/495] make travis happy --- lib/error-matcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 50e7203e..ecb87229 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -65,7 +65,7 @@ module.exports = (function () { ErrorMatcher.prototype.set = function (regex, cwd, output) { try { this.regex = XRegExp(regex); - } catch(err) { + } catch (err) { this.regex = null; return this.emit('error', 'Error parsing regex:\n' + err); } From cbc49037a9ec8827330e1b57b989baf22fd6458e Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 13 Jul 2015 13:28:59 +0200 Subject: [PATCH 100/495] changed to --- lib/error-matcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 02f44ed6..f15833d9 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -68,7 +68,7 @@ module.exports = (function () { var matchIndex; for (matchIndex in this.currentMatch) { var search = _.escape(this.currentMatch[matchIndex][0]); - var replace = '$&'; + var replace = '$&'; output = output.replace(search, replace); } this.emit('replace', output); From e1f0245f81e94bcbe53f21a70448bbd47740cbeb Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 13 Jul 2015 14:13:57 +0200 Subject: [PATCH 101/495] extracted gotoMatch --- lib/error-matcher.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index f15833d9..9b9a72e3 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -24,7 +24,12 @@ module.exports = (function () { util.inherits(ErrorMatcher, EventEmitter); ErrorMatcher.prototype._goto = function () { - var match = this.currentMatch[0]; + this.gotoMatch(this.currentMatch[0].id); + this.currentMatch.push(this.currentMatch.shift()); + }; + + ErrorMatcher.prototype.gotoMatch = function (id) { + var match = _.findWhere(this.currentMatch, {id: id}); if (match.absFile) { atom.notifications.addWarning('`absFile` is deprecated.', { detail: 'You should name your match `file` only. It handles both relative and absolute paths.' @@ -43,7 +48,6 @@ module.exports = (function () { var row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ var col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ - this.currentMatch.push(this.currentMatch.shift()); fs.exists(file, function (exists) { if (!exists) { From 71998af9e6ada38ca592441a746e6a13478dbfbc Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 13 Jul 2015 20:43:44 +0200 Subject: [PATCH 102/495] implementend clickable errors --- lib/build-view.js | 4 +++- lib/build.js | 4 ++-- lib/error-matcher.js | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 3a0ea83a..af6b97d5 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -2,6 +2,7 @@ var _ = require('lodash'); var View = require('atom-space-pen-views').View; +var $ = require('atom-space-pen-views').$; var cscompatability = require('./cscompatability'); var GoogleAnalytics = require('./google-analytics'); var Convert = require('ansi-to-html'); @@ -183,9 +184,10 @@ module.exports = (function() { this.output.scrollTop(this.output[0].scrollHeight); }; - BuildView.prototype.replace = function(text) { + BuildView.prototype.replace = function(text, onclick) { this.output.empty(); this.output.append('
  • ' + (this.a2h.toHtml(text)) + '
  • '); + this.output.find('a').on('click', function() {onclick($(this).attr('id'));}); this.output.scrollTop(this.output[0].scrollHeight); }; diff --git a/lib/build.js b/lib/build.js index a1d0f4e5..68985aa4 100644 --- a/lib/build.js +++ b/lib/build.js @@ -125,8 +125,8 @@ module.exports = { this.buildView.scrollTo(type, id); }.bind(this)); - this.errorMatcher.on('replace', function(text) { - this.buildView.replace(text); + this.errorMatcher.on('replace', function(text, onclick) { + this.buildView.replace(text, onclick); }.bind(this)); this.refreshTargets().catch(function(e) {}); diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 9b9a72e3..aaea32c3 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -29,6 +29,7 @@ module.exports = (function () { }; ErrorMatcher.prototype.gotoMatch = function (id) { + var match = _.findWhere(this.currentMatch, {id: id}); if (match.absFile) { atom.notifications.addWarning('`absFile` is deprecated.', { @@ -65,7 +66,7 @@ module.exports = (function () { ErrorMatcher.prototype._parse = function () { this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match, i) { match.type = 'error'; - match.id = i; + match.id = 'error-' + i; this.push(match); }, []); var output = _.escape(this.output); @@ -75,7 +76,7 @@ module.exports = (function () { var replace = '$&'; output = output.replace(search, replace); } - this.emit('replace', output); + this.emit('replace', output, this.gotoMatch.bind(this)); return this.currentMatch.length; }; From 0416e75d84f0fbba64c49c7695c5eb5bc67d5a7e Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 13 Jul 2015 20:46:25 +0200 Subject: [PATCH 103/495] renamed some functions --- lib/error-matcher.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index aaea32c3..8bf5cad2 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -23,12 +23,12 @@ module.exports = (function () { util.inherits(ErrorMatcher, EventEmitter); - ErrorMatcher.prototype._goto = function () { - this.gotoMatch(this.currentMatch[0].id); + ErrorMatcher.prototype._gotoNext = function () { + this._goto(this.currentMatch[0].id); this.currentMatch.push(this.currentMatch.shift()); }; - ErrorMatcher.prototype.gotoMatch = function (id) { + ErrorMatcher.prototype._goto = function (id) { var match = _.findWhere(this.currentMatch, {id: id}); if (match.absFile) { @@ -76,7 +76,7 @@ module.exports = (function () { var replace = '$&'; output = output.replace(search, replace); } - this.emit('replace', output, this.gotoMatch.bind(this)); + this.emit('replace', output, this._goto.bind(this)); return this.currentMatch.length; }; @@ -98,7 +98,7 @@ module.exports = (function () { return; } - this._goto(); + this._gotoNext(); }; ErrorMatcher.prototype.matchFirst = function () { @@ -112,7 +112,7 @@ module.exports = (function () { return; } - this._goto(); + this._gotoNext(); }; return ErrorMatcher; From 754d1fab02bc6b6cbfd27e111e43e8f203eda268 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 13 Jul 2015 21:15:40 +0200 Subject: [PATCH 104/495] make travis happy --- lib/error-matcher.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 8bf5cad2..b09d790e 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -29,8 +29,7 @@ module.exports = (function () { }; ErrorMatcher.prototype._goto = function (id) { - - var match = _.findWhere(this.currentMatch, {id: id}); + var match = _.findWhere(this.currentMatch, { id: id }); if (match.absFile) { atom.notifications.addWarning('`absFile` is deprecated.', { detail: 'You should name your match `file` only. It handles both relative and absolute paths.' @@ -49,7 +48,6 @@ module.exports = (function () { var row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ var col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ - fs.exists(file, function (exists) { if (!exists) { return this.emit('error', 'Matched file does not exist: ' + file); From 4861ac7e6e564df858f0384ed108bf0ccd0c4d79 Mon Sep 17 00:00:00 2001 From: Blake Winton Date: Wed, 15 Jul 2015 15:52:25 -0400 Subject: [PATCH 105/495] Use a service instead of hard-coding all the tools. See https://github.com/bwinton/atom-build-jpm or https://github.com/bwinton/atom-build-markdown for example service providers. --- lib/build.js | 12 +++++++++++- package.json | 7 +++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 83a19fb9..b1ed8b74 100644 --- a/lib/build.js +++ b/lib/build.js @@ -13,6 +13,7 @@ var BuildView = require('./build-view'); var GoogleAnalytics = require('./google-analytics'); var ErrorMatcher = require('./error-matcher'); var tools = require('./tools'); +var extra_tools = []; function BuildError(name, message) { this.name = name; @@ -185,7 +186,7 @@ module.exports = { throw new BuildError('No active project', 'No project is active, don\'t know what to build...'); } - return _.filter(tools, function (tool) { + return _.filter(tools.concat(extra_tools), function (tool) { return tool.isEligable(path); }); }) @@ -437,5 +438,14 @@ module.exports = { } else { this.buildView.reset(); } + }, + + consumeBuilder: function (builders) { + if (!(builders instanceof Array)) { + builders = [builders]; + } + builders.forEach(function (builder) { + extra_tools.push(builder); + }); } }; diff --git a/package.json b/package.json index 8417c9d9..013d3f3d 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,13 @@ "jshint": "^2.5.11", "jscs": "^1.9.0" }, + "consumedServices": { + "builder": { + "versions": { + "^1.0.0": "consumeBuilder" + } + } + }, "scripts": { "test": "./node_modules/.bin/jscs lib/*.js spec/*.js && ./node_modules/.bin/jshint lib/*.js spec/*.js" }, From 56a6d235dfc96693bc7262dfd2908ecdf92a51d8 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Wed, 15 Jul 2015 22:07:28 +0200 Subject: [PATCH 106/495] fail, if there is a error match --- lib/build.js | 10 ++++++---- lib/error-matcher.js | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/build.js b/lib/build.js index 83a19fb9..9a435dda 100644 --- a/lib/build.js +++ b/lib/build.js @@ -333,15 +333,17 @@ module.exports = { }.bind(this)); this.child.on('close', function(exitCode) { - this.buildView.buildFinished(0 === exitCode); - if (0 === exitCode) { + var t = this.targets[this.activeTarget]; + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), Buffer.concat([ this.stdout, this.stderr ]).toString('utf8')); + + var success = 0 === exitCode && !this.errorMatcher.hasMatch(); + this.buildView.buildFinished(success); + if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); this.finishedTimer = setTimeout(function() { this.buildView.detach(); }.bind(this), 1000); } else { - var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), Buffer.concat([ this.stdout, this.stderr ]).toString('utf8')); if (atom.config.get('build.scrollOnError')) { this.errorMatcher.matchFirst(); } diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 6d0aaafa..99383470 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -97,5 +97,9 @@ module.exports = (function () { this._goto(); }; + ErrorMatcher.prototype.hasMatch = function () { + return this.regex && 0 !== this._parse(); + }; + return ErrorMatcher; })(); From ceebd0b43cb1fe9c91c5f58a623bb17f06d29c97 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 15 Jul 2015 23:26:29 +0200 Subject: [PATCH 107/495] ErrorMatch: invalid regex spec Added test when the regular expression is invalid in the error matching column. --- spec/build-error-match-spec.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 00430a15..4fde658e 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -297,5 +297,29 @@ describe('Error Match', function() { expect(bufferPosition.column).toEqual(7); }); }); + + it('should show an error if regex is invalid', function () { + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'return 1', + errorMatch: '(invalidRegex' + })); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + expect(atom.notifications.getNotifications().length).toEqual(1); + + var notification = atom.notifications.getNotifications()[0]; + expect(notification.getType()).toEqual('error'); + expect(notification.getMessage()).toEqual('Error matching failed!'); + expect(notification.options.detail).toMatch(/Unterminated group/); + }); + }); }); }); From 52e35cd4dd8a71cc7a77b03b7b07c7cc8af48089 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 15 Jul 2015 23:48:14 +0200 Subject: [PATCH 108/495] Prepare 0.41.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8417c9d9..661571a6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.40.0", + "version": "0.41.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 89d9a655a7244ebf79aa41d925486333ce7b3125 Mon Sep 17 00:00:00 2001 From: Jordan Klassen Date: Fri, 19 Jun 2015 16:38:58 -0700 Subject: [PATCH 109/495] Only use project path if it contains active file --- lib/build.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 83a19fb9..8c53ba25 100644 --- a/lib/build.js +++ b/lib/build.js @@ -268,13 +268,16 @@ module.exports = { var editor = atom.workspace.getActiveTextEditor(); if (editor && 'untitled' !== editor.getTitle()) { var activeFile = fs.realpathSync(editor.getPath()); + var activeFilePath = path.dirname(activeFile); value = value.replace('{FILE_ACTIVE}', activeFile); - value = value.replace('{FILE_ACTIVE_PATH}', path.dirname(activeFile)); + value = value.replace('{FILE_ACTIVE_PATH}', activeFilePath); value = value.replace('{FILE_ACTIVE_NAME}', path.basename(activeFile)); value = value.replace('{FILE_ACTIVE_NAME_BASE}', path.basename(activeFile, path.extname(activeFile))); } - - value = value.replace('{PROJECT_PATH}', fs.realpathSync(atom.project.getPaths()[0])); + var projectPaths = atom.project.getPaths().map(function(projectPath) { return fs.realpathSync(projectPath); }); + var projectPath = projectPaths.filter(function(projectPath) { return activeFilePath.startsWith(projectPath); })[0]; + if (!projectPath) { projectPath = projectPaths[0]; } + value = value.replace('{PROJECT_PATH}', projectPath); if (atom.project.getRepositories[0]) { value = value.replace('{REPO_BRANCH_SHORT}', atom.project.getRepositories()[0].getShortHead()); } From e383c1f76b5ce69cf61a1a31a1e86d3b40df786c Mon Sep 17 00:00:00 2001 From: Jordan Klassen Date: Thu, 16 Jul 2015 02:41:37 +0000 Subject: [PATCH 110/495] Fix test errors --- lib/build.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 8c53ba25..22eef14a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -274,9 +274,8 @@ module.exports = { value = value.replace('{FILE_ACTIVE_NAME}', path.basename(activeFile)); value = value.replace('{FILE_ACTIVE_NAME_BASE}', path.basename(activeFile, path.extname(activeFile))); } - var projectPaths = atom.project.getPaths().map(function(projectPath) { return fs.realpathSync(projectPath); }); - var projectPath = projectPaths.filter(function(projectPath) { return activeFilePath.startsWith(projectPath); })[0]; - if (!projectPath) { projectPath = projectPaths[0]; } + var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { try { return fs.realpathSync(projectPath); } catch(e) {} }); + var projectPath = _.find(projectPaths, function(projectPath) { return activeFilePath && activeFilePath.startsWith(projectPath); }) || projectPaths[0]; value = value.replace('{PROJECT_PATH}', projectPath); if (atom.project.getRepositories[0]) { value = value.replace('{REPO_BRANCH_SHORT}', atom.project.getRepositories()[0].getShortHead()); From ac4c3c9b74afd582ccf2e842c6f5abeb24f1eb7e Mon Sep 17 00:00:00 2001 From: Jordan Klassen Date: Thu, 16 Jul 2015 02:44:49 +0000 Subject: [PATCH 111/495] Fix code style issue --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 22eef14a..f6b58d14 100644 --- a/lib/build.js +++ b/lib/build.js @@ -274,7 +274,7 @@ module.exports = { value = value.replace('{FILE_ACTIVE_NAME}', path.basename(activeFile)); value = value.replace('{FILE_ACTIVE_NAME_BASE}', path.basename(activeFile, path.extname(activeFile))); } - var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { try { return fs.realpathSync(projectPath); } catch(e) {} }); + var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { try { return fs.realpathSync(projectPath); } catch (e) {} }); var projectPath = _.find(projectPaths, function(projectPath) { return activeFilePath && activeFilePath.startsWith(projectPath); }) || projectPaths[0]; value = value.replace('{PROJECT_PATH}', projectPath); if (atom.project.getRepositories[0]) { From 28a40e6ebf2c8ee77cbaf21aa38913252fd97789 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 10:33:43 +0200 Subject: [PATCH 112/495] fixed styling issues --- lib/build-view.js | 4 +++- lib/build.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index af6b97d5..7134d1c4 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -187,7 +187,9 @@ module.exports = (function() { BuildView.prototype.replace = function(text, onclick) { this.output.empty(); this.output.append('
  • ' + (this.a2h.toHtml(text)) + '
  • '); - this.output.find('a').on('click', function() {onclick($(this).attr('id'));}); + this.output.find('a').on('click', function() { + onclick($(this).attr('id')); + }); this.output.scrollTop(this.output[0].scrollHeight); }; diff --git a/lib/build.js b/lib/build.js index 68985aa4..97d37bd8 100644 --- a/lib/build.js +++ b/lib/build.js @@ -349,7 +349,7 @@ module.exports = { }.bind(this), 1000); } else { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); if (atom.config.get('build.scrollOnError')) { this.errorMatcher.matchFirst(); } From c1bf574988d599c6f31736b4791b82f6398e92d0 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 11:01:23 +0200 Subject: [PATCH 113/495] fixed bug: same string gets matched two times -> highlight both times --- lib/error-matcher.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index b09d790e..f50cd1cb 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -67,13 +67,18 @@ module.exports = (function () { match.id = 'error-' + i; this.push(match); }, []); - var output = _.escape(this.output); - var matchIndex; - for (matchIndex in this.currentMatch) { - var search = _.escape(this.currentMatch[matchIndex][0]); - var replace = '$&'; - output = output.replace(search, replace); + + var output = ''; + var lastEnd = 0; + for (var matchIndex in this.currentMatch) { + var match = this.currentMatch[matchIndex]; + + output += _.escape(this.output.substr(lastEnd, match.index - lastEnd)); + output += '' + _.escape(match[0]) + ''; + lastEnd = match.index + match[0].length; } + output += _.escape(this.output.substr(lastEnd)); + this.emit('replace', output, this._goto.bind(this)); return this.currentMatch.length; }; From ed05817d4b8fd6eabba2abaf23ee2b42c9fe3678 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 11:19:05 +0200 Subject: [PATCH 114/495] fixed no newline after Executing... --- lib/build.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 97d37bd8..8669bfb9 100644 --- a/lib/build.js +++ b/lib/build.js @@ -336,8 +336,8 @@ module.exports = { }.bind(this)); this.child.on('error', function(err) { - this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec); - this.buildView.append(/\s/.test(this.cmd.exec) ? '`cmd` cannot contain space. Use `args` for arguments.' : ''); + this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec + '\n'); + this.buildView.append(/\s/.test(this.cmd.exec) ? '`cmd` cannot contain space. Use `args` for arguments.\n' : ''); }.bind(this)); this.child.on('close', function(exitCode) { @@ -359,7 +359,7 @@ module.exports = { }.bind(this)); this.buildView.buildStarted(); - this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ')); + this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ') + '\n'); }).catch(BuildError, function (error) { if (source === 'save') { // If there is no eligible build tool, and cause of build was a save, stay quiet. From 7d94782c69b3461df0778bbbd99c095acecfc043 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 11:47:52 +0200 Subject: [PATCH 115/495] fixed merge error --- lib/error-matcher.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 07bb2795..0bd4cde9 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -63,11 +63,10 @@ module.exports = (function () { ErrorMatcher.prototype._parse = function () { this.currentMatch = []; - var regexIndex; - for (regexIndex in this.regex) { + for (var regexIndex in this.regex) { XRegExp.forEach(this.output, this.regex[regexIndex], function (match, i) { match.type = 'error'; - match.id = i; + match.id = 'error-' + i; this.push(match); }, this.currentMatch); } From b13096287a79a28c437b0f57300b4005062f39dd Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 12:02:32 +0200 Subject: [PATCH 116/495] sort matches correctly --- lib/error-matcher.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 0bd4cde9..134efd45 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -63,19 +63,29 @@ module.exports = (function () { ErrorMatcher.prototype._parse = function () { this.currentMatch = []; + var matchFunction = function (match, i) { + match.type = 'error'; + match.id = 'error-' + regexIndex + '-' + i; + this.push(match); + }; for (var regexIndex in this.regex) { - XRegExp.forEach(this.output, this.regex[regexIndex], function (match, i) { - match.type = 'error'; - match.id = 'error-' + i; - this.push(match); - }, this.currentMatch); + XRegExp.forEach(this.output, this.regex[regexIndex], matchFunction, this.currentMatch); } + this.currentMatch.sort(function(a, b) { + return a.index - b.index; + }); + var output = ''; var lastEnd = 0; for (var matchIndex in this.currentMatch) { var match = this.currentMatch[matchIndex]; + if (match.index < lastEnd) { + // overlapping matches, only highlight first + continue; + } + output += _.escape(this.output.substr(lastEnd, match.index - lastEnd)); output += '' + _.escape(match[0]) + ''; lastEnd = match.index + match[0].length; From 3c3874b4716cd8523b21d8f114f3d02abf9c972f Mon Sep 17 00:00:00 2001 From: Blake Winton Date: Fri, 17 Jul 2015 12:57:45 -0400 Subject: [PATCH 117/495] Add a disposable to handle the case when the builder gets removed or disabled. --- lib/build.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index b1ed8b74..b6b7846e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -6,6 +6,7 @@ var fs = Promise.promisifyAll(require('fs')); var path = require('path'); var _ = require('lodash'); var Promise = require('bluebird'); +var Disposable = require('atom').Disposable; var SaveConfirmView = require('./save-confirm-view'); var TargetsView = require('./targets-view'); @@ -444,8 +445,9 @@ module.exports = { if (!(builders instanceof Array)) { builders = [builders]; } - builders.forEach(function (builder) { - extra_tools.push(builder); + extra_tools = _.union(extra_tools, builders); + return new Disposable(function () { + extra_tools = _.difference(extra_tools, builders); }); } }; From 6634175cf8057fe7d0ff41893b9595df1a6713d5 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 11 Jul 2015 09:49:47 +0200 Subject: [PATCH 118/495] fixed build command spawning subprocesses --- lib/build.js | 5 +++-- package.json | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) mode change 100644 => 100755 package.json diff --git a/lib/build.js b/lib/build.js index 4306013e..f4dd3421 100644 --- a/lib/build.js +++ b/lib/build.js @@ -7,6 +7,7 @@ var path = require('path'); var _ = require('lodash'); var Promise = require('bluebird'); var Disposable = require('atom').Disposable; +var kill = require('tree-kill'); var SaveConfirmView = require('./save-confirm-view'); var TargetsView = require('./targets-view'); @@ -131,7 +132,7 @@ module.exports = { this.customFileWatcher.close(); } if (this.child) { - this.child.kill('SIGKILL'); + kill(this.child.pid); } clearTimeout(this.finishedTimer); }, @@ -380,7 +381,7 @@ module.exports = { }.bind(this)); try { - this.child.kill(); + kill(this.child.pid); } catch (e) { /* Something may have happened to the child (e.g. terminated by itself). Ignore this. */ } diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 9600b5f7..a129081f --- a/package.json +++ b/package.json @@ -9,15 +9,16 @@ "atom": ">=0.50.0" }, "dependencies": { - "lodash": "^3.8.0", - "bluebird": "^2.9.25", "ansi-to-html": "^0.3.0", - "temp": "^0.8.1", - "fs-extra": "^0.18.3", "atom-space-pen-views": "^2.0.3", - "xregexp": "^2.0.0", + "bluebird": "^2.9.25", + "fs-extra": "^0.18.3", + "getmac": "^1.0.7", + "lodash": "^3.8.0", "node-uuid": "^1.4.3", - "getmac": "^1.0.7" + "temp": "^0.8.1", + "tree-kill": "^0.1.1", + "xregexp": "^2.0.0" }, "devDependencies": { "jshint": "^2.5.11", From 7a254e23bfd05285ab787ff523c04cec71b65f96 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 10:27:49 +0200 Subject: [PATCH 119/495] kill using SIGKILL --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index f4dd3421..4be09f32 100644 --- a/lib/build.js +++ b/lib/build.js @@ -381,7 +381,7 @@ module.exports = { }.bind(this)); try { - kill(this.child.pid); + kill(this.child.pid, 'SIGKILL'); } catch (e) { /* Something may have happened to the child (e.g. terminated by itself). Ignore this. */ } From 9db2a77824f24867ef4fc6d02a197ef2613adf81 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Thu, 16 Jul 2015 10:30:07 +0200 Subject: [PATCH 120/495] SIGKILL at the correct time --- lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 4be09f32..5268b3b4 100644 --- a/lib/build.js +++ b/lib/build.js @@ -132,7 +132,7 @@ module.exports = { this.customFileWatcher.close(); } if (this.child) { - kill(this.child.pid); + kill(this.child.pid, 'SIGKILL'); } clearTimeout(this.finishedTimer); }, @@ -381,7 +381,7 @@ module.exports = { }.bind(this)); try { - kill(this.child.pid, 'SIGKILL'); + kill(this.child.pid); } catch (e) { /* Something may have happened to the child (e.g. terminated by itself). Ignore this. */ } From 46853edb195e7fd016d3b571e92c44f855168ee4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 17 Jul 2015 23:54:17 +0200 Subject: [PATCH 121/495] Code style fixes --- lib/build.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 5268b3b4..9b208a82 100644 --- a/lib/build.js +++ b/lib/build.js @@ -277,8 +277,15 @@ module.exports = { value = value.replace('{FILE_ACTIVE_NAME}', path.basename(activeFile)); value = value.replace('{FILE_ACTIVE_NAME_BASE}', path.basename(activeFile, path.extname(activeFile))); } - var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { try { return fs.realpathSync(projectPath); } catch (e) {} }); - var projectPath = _.find(projectPaths, function(projectPath) { return activeFilePath && activeFilePath.startsWith(projectPath); }) || projectPaths[0]; + var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { + try { + return fs.realpathSync(projectPath); + } catch (e) {} + }); + var projectPath = _.find(projectPaths, function(projectPath) { + return activeFilePath && activeFilePath.startsWith(projectPath); + }) || projectPaths[0]; + value = value.replace('{PROJECT_PATH}', projectPath); if (atom.project.getRepositories[0]) { value = value.replace('{REPO_BRANCH_SHORT}', atom.project.getRepositories()[0].getShortHead()); @@ -446,7 +453,7 @@ module.exports = { consumeBuilder: function (builders) { if (!(builders instanceof Array)) { - builders = [builders]; + builders = [ builders ]; } extra_tools = _.union(extra_tools, builders); return new Disposable(function () { From fda4278427c7eceeb9a0b028deb6d4e3f718b5c5 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 19 Jul 2015 23:56:22 +0200 Subject: [PATCH 122/495] Prepare 0.42.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 package.json diff --git a/package.json b/package.json old mode 100755 new mode 100644 index a129081f..d1c8cb8d --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.41.0", + "version": "0.42.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 0f64928ebd0bc51b20966cbaa97048ccb8f05cd8 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 20 Jul 2015 00:37:27 +0200 Subject: [PATCH 123/495] README: Service API --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index 43d5777e..8bed8dfd 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,47 @@ to cycle through the errors (in the order they appear, first on stderr then on s Often, the first error is the most interesting since other errors tend to be secondary faults caused by that first one. To jump to the first error you can use `cmd-alt-h` (OS X) or `ctrl-alt-h` (Linux/Windows) at any point to go to the first error. +## Service API (for package developers) + +Another package may provide build information to the `build`-package by implementing its service API. +The package should integrate via the service API. This is typically done in `package.json`: + +```json +{ + + "providedServices": { + "builder": { + "description": "Description of the build configurations this package gives", + "versions": { + "1.0.0": "providingFunction" + } + } + } +}, +``` + +The `build`-package will then call `providingFunction` when activated and expects an +object in return: +```javascript +{ + niceName: 'string', + isEligable: function (path) {}, + settings: function (path) {} +} +``` + +The `niceName` is esthetic only and should be a `string` which is a human readable +description of the build configuration is provided. + +`isEligable` should be a function which must return synchronously. It will get one +argument, `path`, which is the root folder of the currently active project in Atom. +It should return `true` or `false` indicating if it can build that folder into something +sensible. Typically look for the existence of a build file such as `gulpfile.js` or `Makefile`. + +`settings` must return a promise. It is called when it is time to build the project. +It can provide anything which is allowed by the [custom build configuration](#custom-build-config). +This includes the command, `cmd`, to execute, any arguments, `args`, and so on. + ## Analytics The `atom-build` package uses google analytics to keep track of which features are in use From 8eb378b081d61e574b8cff16ecbadb1eed71a8cf Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 22 Jul 2015 00:13:32 +0200 Subject: [PATCH 124/495] Error Matcher: Remove deprecated absFile --- lib/error-matcher.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index a6c42a99..762c5854 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -30,29 +30,22 @@ module.exports = (function () { ErrorMatcher.prototype._goto = function (id) { var match = _.findWhere(this.currentMatch, { id: id }); - if (match.absFile) { - atom.notifications.addWarning('`absFile` is deprecated.', { - detail: 'You should name your match `file` only. It handles both relative and absolute paths.' - }); - } - - if (!match.file && !match.absFile) { + if (!match.file) { return this.emit('error', 'Did not match any file. Don\'t know what to open.'); } - var file = match.file ? match.file : match.absFile; - if (!path.isAbsolute(file)) { - file = this.cwd + path.sep + file; + if (!path.isAbsolute(match.file)) { + match.file = this.cwd + path.sep + match.file; } var row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ var col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ - fs.exists(file, function (exists) { + fs.exists(match.file, function (exists) { if (!exists) { - return this.emit('error', 'Matched file does not exist: ' + file); + return this.emit('error', 'Matched file does not exist: ' + match.file); } - atom.workspace.open(file, { + atom.workspace.open(match.file, { initialLine: row, initialColumn: col, searchAllPanes: true From 71b77d108f17ecdbc65c492125ba1ce8cd88e028 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 22 Jul 2015 00:35:39 +0200 Subject: [PATCH 125/495] Code Style fixes --- lib/build.js | 9 ++------- lib/error-matcher.js | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/build.js b/lib/build.js index 14db6673..87690f3c 100644 --- a/lib/build.js +++ b/lib/build.js @@ -124,13 +124,8 @@ module.exports = { atom.notifications.addError('Error matching failed!', { detail: message }); }); - this.errorMatcher.on('scroll', function(type, id) { - this.buildView.scrollTo(type, id); - }.bind(this)); - - this.errorMatcher.on('replace', function(text, onclick) { - this.buildView.replace(text, onclick); - }.bind(this)); + this.errorMatcher.on('scroll', this.buildView.scrollTo.bind(this.buildView)); + this.errorMatcher.on('replace', this.buildView.replace.bind(this.buildView)); this.refreshTargets().catch(function(e) {}); }, diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 762c5854..c6440bbd 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -67,7 +67,7 @@ module.exports = (function () { var match = this.currentMatch[matchIndex]; output += _.escape(this.output.substr(lastEnd, match.index - lastEnd)); - output += '' + _.escape(match[0]) + ''; + output += util.format('%s', match.type, match.id, _.escape(match[0])); lastEnd = match.index + match[0].length; } output += _.escape(this.output.substr(lastEnd)); From ef4a900749ecc46e3cac3cb4097b3497390f50a3 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Wed, 22 Jul 2015 00:48:03 +0200 Subject: [PATCH 126/495] fixed indentation --- lib/error-matcher.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 20fd4bfa..6af2609e 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -97,7 +97,7 @@ module.exports = (function () { curRegex = XRegExp(regex[i]); } catch (err) { this.emit('error', 'Error parsing regex:\n' + err); - } + } if(curRegex !== null) { this.regex.push(curRegex); } @@ -105,7 +105,7 @@ module.exports = (function () { if(this.regex.length === 0) { this.regex = 0; } - + this.cwd = cwd; this.output = output; this.currentMatch = []; From 8a8e2afd20162f2fcdca8c761f2d5003a9705ad0 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 22 Jul 2015 01:08:57 +0200 Subject: [PATCH 127/495] Spec: ErrorMatch scroll panel --- spec/build-error-match-spec.js | 66 +++++++++++++++++++ .../.atom-build.error-match-long-output.json | 7 ++ 2 files changed, 73 insertions(+) create mode 100644 spec/fixture/.atom-build.error-match-long-output.json diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 4fde658e..f61ff485 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -9,6 +9,7 @@ describe('Error Match', function() { var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; var errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json'; var errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; + var errorMatchLongOutputAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-long-output.json'; var directory = null; var workspaceElement = null; @@ -321,5 +322,70 @@ describe('Error Match', function() { expect(notification.options.detail).toMatch(/Unterminated group/); }); }); + + it('should scroll the build panel to the text of the error', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waits(100); + runs(function() { + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waits(100); + runs(function() { + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(135); + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waits(100); + runs(function() { + /* Should wrap around to first match */ + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + }); + }); + + it('match-first should scroll the build panel', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waits(100); + runs(function() { + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waits(100); + runs(function() { + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(135); + atom.commands.dispatch(workspaceElement, 'build:error-match-first'); + }); + + waits(100); + runs(function() { + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + }); + }); }); }); diff --git a/spec/fixture/.atom-build.error-match-long-output.json b/spec/fixture/.atom-build.error-match-long-output.json new file mode 100644 index 00000000..83670617 --- /dev/null +++ b/spec/fixture/.atom-build.error-match-long-output.json @@ -0,0 +1,7 @@ +{ + "cmd": "echo \"\n\n\n\n\n\nfile:$FILE,line:3,column:8\n\n\n\n\n\nfile:$FILE,line:2,column:5; exit 1", + "env": { + "FILE": ".atom-build.json" + }, + "errorMatch": "file:(?[^$,]+),line:(?\\d+),column:(?\\d+)" +} From 9dd4cca2367a00ded0b82acd00e6628c260d9582 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 22 Jul 2015 01:13:56 +0200 Subject: [PATCH 128/495] Build: replace all occurances --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 87690f3c..60702403 100644 --- a/lib/build.js +++ b/lib/build.js @@ -267,7 +267,7 @@ module.exports = { replace: function(value) { var env = _.extend(_.clone(process.env), this.cmd.env); - value = value.replace(/\$(\w+)/, function(match, name) { + value = value.replace(/\$(\w+)/g, function(match, name) { return name in env ? env[name] : match; }); From 02b04be2ffff7de722d39d8c39a1c05d079bf522 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Wed, 22 Jul 2015 09:13:14 +0200 Subject: [PATCH 129/495] fixed styling --- lib/build.js | 2 +- lib/error-matcher.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/build.js b/lib/build.js index f696b421..e67812eb 100644 --- a/lib/build.js +++ b/lib/build.js @@ -362,7 +362,7 @@ module.exports = { } else { var t = this.targets[this.activeTarget]; var errorMatch = t.errorMatch; - if(!(errorMatch instanceof Array)) { + if (!(errorMatch instanceof Array)) { errorMatch = [errorMatch]; } this.errorMatcher.set(errorMatch, this.replace(t.cwd), this.buildView.output.text()); diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 6af2609e..46cb506f 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -91,18 +91,18 @@ module.exports = (function () { ErrorMatcher.prototype.set = function (regex, cwd, output) { this.regex = []; - for(var i in regex) { + for (var i in regex) { var curRegex = null; try { curRegex = XRegExp(regex[i]); } catch (err) { this.emit('error', 'Error parsing regex:\n' + err); } - if(curRegex !== null) { + if (curRegex !== null) { this.regex.push(curRegex); } } - if(this.regex.length === 0) { + if (this.regex.length === 0) { this.regex = 0; } From 563753ee624a5ac80e9a496ebab0a1a59a41a40d Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 25 Jul 2015 11:35:43 +0200 Subject: [PATCH 130/495] only parse the output one time and highlight on build finished --- lib/build-view.js | 1 - lib/error-matcher.js | 14 ++++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 7134d1c4..a3827cf0 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -190,7 +190,6 @@ module.exports = (function() { this.output.find('a').on('click', function() { onclick($(this).attr('id')); }); - this.output.scrollTop(this.output[0].scrollHeight); }; BuildView.prototype.scrollTo = function(type, id) { diff --git a/lib/error-matcher.js b/lib/error-matcher.js index c6440bbd..a3b13759 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -24,6 +24,10 @@ module.exports = (function () { util.inherits(ErrorMatcher, EventEmitter); ErrorMatcher.prototype._gotoNext = function () { + if (0 === this.currentMatch.length) { + return; + } + this._goto(this.currentMatch[0].id); this.currentMatch.push(this.currentMatch.shift()); }; @@ -86,6 +90,8 @@ module.exports = (function () { this.cwd = cwd; this.output = output; this.currentMatch = []; + + this._parse(); }; ErrorMatcher.prototype.match = function () { @@ -95,10 +101,6 @@ module.exports = (function () { GoogleAnalytics.sendEvent('errorMatch', 'match'); - if (0 === this.currentMatch.length && 0 === this._parse()) { - return; - } - this._gotoNext(); }; @@ -109,10 +111,6 @@ module.exports = (function () { GoogleAnalytics.sendEvent('errorMatch', 'first'); - if (0 === this._parse()) { - return; - } - this._gotoNext(); }; From fe4a97b6205a36cbddb44e3f7555fcc841b5d34f Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 25 Jul 2015 11:46:13 +0200 Subject: [PATCH 131/495] handle no errorMatcher correctly --- lib/error-matcher.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index a3b13759..7e5d5b00 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -59,6 +59,10 @@ module.exports = (function () { }; ErrorMatcher.prototype._parse = function () { + if (!this.regex) { + return; + } + this.currentMatch = XRegExp.forEach(this.output, this.regex, function (match, i) { match.type = 'error'; match.id = 'error-' + i; @@ -77,12 +81,15 @@ module.exports = (function () { output += _.escape(this.output.substr(lastEnd)); this.emit('replace', output, this._goto.bind(this)); - return this.currentMatch.length; }; ErrorMatcher.prototype.set = function (regex, cwd, output) { try { - this.regex = XRegExp(regex); + if (!regex) { + this.regex = null; + } else { + this.regex = XRegExp(regex); + } } catch (err) { this.regex = null; return this.emit('error', 'Error parsing regex:\n' + err); @@ -95,20 +102,12 @@ module.exports = (function () { }; ErrorMatcher.prototype.match = function () { - if (!this.regex) { - return; - } - GoogleAnalytics.sendEvent('errorMatch', 'match'); this._gotoNext(); }; ErrorMatcher.prototype.matchFirst = function () { - if (!this.regex) { - return; - } - GoogleAnalytics.sendEvent('errorMatch', 'first'); this._gotoNext(); From bab901a88b56d4112cf86b756d18293a23257449 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 25 Jul 2015 12:55:11 +0200 Subject: [PATCH 132/495] fixed gotoFirstError --- lib/error-matcher.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 7e5d5b00..e494b621 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -16,6 +16,7 @@ module.exports = (function () { this.stdout = null; this.stderr = null; this.currentMatch = []; + this.firstMatchId = null; atom.commands.add('atom-workspace', 'build:error-match', this.match.bind(this)); atom.commands.add('atom-workspace', 'build:error-match-first', this.matchFirst.bind(this)); @@ -29,11 +30,20 @@ module.exports = (function () { } this._goto(this.currentMatch[0].id); - this.currentMatch.push(this.currentMatch.shift()); }; ErrorMatcher.prototype._goto = function (id) { var match = _.findWhere(this.currentMatch, { id: id }); + if (!match) { + throw new Error('Can\'t find match with id ' + id); + } + + // rotate to next match + while (this.currentMatch[0] !== match) { + this.currentMatch.push(this.currentMatch.shift()); + } + this.currentMatch.push(this.currentMatch.shift()); + if (!match.file) { return this.emit('error', 'Did not match any file. Don\'t know what to open.'); } @@ -69,6 +79,8 @@ module.exports = (function () { this.push(match); }, []); + this.firstMatchId = this.currentMatch[0].id; + var output = ''; var lastEnd = 0; for (var matchIndex in this.currentMatch) { @@ -110,7 +122,9 @@ module.exports = (function () { ErrorMatcher.prototype.matchFirst = function () { GoogleAnalytics.sendEvent('errorMatch', 'first'); - this._gotoNext(); + if (this.firstMatchId) { + this._goto(this.firstMatchId); + } }; return ErrorMatcher; From 849500c17c789ea9e80b80f8fd3c113d61c739cd Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 25 Jul 2015 13:23:41 +0200 Subject: [PATCH 133/495] finished merge --- lib/error-matcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index a35f97d0..0ad81208 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -128,7 +128,7 @@ module.exports = (function () { }; ErrorMatcher.prototype.hasMatch = function () { - return this.regex && 0 !== this._parse(); + return 0 !== this.currentMatch.length; }; return ErrorMatcher; From 4e86e7256864dd2cdddbf7185c24844cd076e178 Mon Sep 17 00:00:00 2001 From: Gauthier Billot Date: Mon, 27 Jul 2015 11:52:48 +0200 Subject: [PATCH 134/495] Updated error matching in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8bed8dfd..fd64acdf 100644 --- a/README.md +++ b/README.md @@ -102,14 +102,14 @@ the output of your build command and opens the correct file, row and column of the error. For instance: ```bash -a.c:4:26: error: expected ';' after expression +../foo/bar/a.c:4:26: error: expected ';' after expression printf("hello world\n") ^ ; 1 error generated. ``` -Would be matched with the regular expression: `^(?[^\\.]+.c):(?\\d+):(?\\d+)`. +Would be matched with the regular expression: `\n(?[\\/0-9a-zA-Z\\._]+):(?\\d+):(?\\d+)`. After the build has failed, pressing `cmd-alt-g` (OS X) or `ctrl-alt-g` (Linux/Windows), `a.c` would be opened and the cursor would be placed at row 4, column 26. From 226e9b7931ee1c066d5ecd8b38ebdf551ac74198 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 6 Aug 2015 18:52:55 +0200 Subject: [PATCH 135/495] Prepare 0.43.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d1c8cb8d..11758652 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.42.0", + "version": "0.43.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From d3693f30e4310be898ed503fc8b14794b7b91739 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 8 Aug 2015 09:39:47 +0200 Subject: [PATCH 136/495] Use babel Added babel so that es6 features can be used. Removed dependency on Bluebird. --- .jshintrc | 2 ++ lib/build-view.js | 1 + lib/build.js | 47 ++++++++++++++++------------------ lib/cscompatability.js | 1 + lib/error-matcher.js | 1 + lib/google-analytics.js | 1 + lib/save-confirm-view.js | 1 + lib/targets-view.js | 2 +- lib/tools/Cargo.js | 1 + lib/tools/Elixir.js | 1 + lib/tools/Grunt.js | 5 ++-- lib/tools/atom-build.js | 1 + lib/tools/gulp-parser-task.js | 2 +- lib/tools/gulp.js | 4 +-- lib/tools/index.js | 3 +++ lib/tools/make.js | 1 + lib/tools/npm_apm.js | 1 + package.json | 3 +-- spec/build-confirm-spec.js | 5 ++-- spec/build-error-match-spec.js | 5 ++-- spec/build-keymap-spec.js | 5 ++-- spec/build-spec.js | 12 ++++----- spec/build-targets-spec.js | 36 +++++++++++++------------- spec/build-visible-spec.js | 18 ++++++++----- spec/spec-helpers.js | 41 +++++++++++++++++++---------- 25 files changed, 117 insertions(+), 83 deletions(-) diff --git a/.jshintrc b/.jshintrc index 07eb92e9..8174af36 100644 --- a/.jshintrc +++ b/.jshintrc @@ -14,6 +14,7 @@ "expr": true, // Allow expressions where normally you would expect to see assignments or function calls. "onecase": true, // Allow switches with only one case (not counting default) "sub": true, // Allow using [] notation when it can also be expressed in dot notation: person['name'] vs. person.name. + "esnext": true, // Environment "node": true, // Define common browser globals: require, nodule, etc. @@ -33,6 +34,7 @@ "afterEach": false, "describe": false, "it": false, + "xit": false, "waits": false, "waitsFor": false, "waitsForPromise": false, diff --git a/lib/build-view.js b/lib/build-view.js index 7134d1c4..8e7f6f69 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var _ = require('lodash'); diff --git a/lib/build.js b/lib/build.js index 60702403..43ea0d88 100644 --- a/lib/build.js +++ b/lib/build.js @@ -1,11 +1,10 @@ +'use babel'; 'use strict'; var child_process = require('child_process'); -var Promise = require('bluebird'); -var fs = Promise.promisifyAll(require('fs')); +var fs = require('fs'); var path = require('path'); var _ = require('lodash'); -var Promise = require('bluebird'); var Disposable = require('atom').Disposable; var kill = require('tree-kill'); @@ -179,12 +178,11 @@ module.exports = { } return Promise.resolve(tools) - .bind(this) .then(function () { this.customFileWatcher = fs.watch(customFile, function () { this.refreshTargets(); }.bind(this)); - }) + }.bind(this)) .catch(function(err) { /* Unable to watch file. Updates to custom file will require manual refresh */ }) .then(function () { if (!path) { @@ -211,7 +209,7 @@ module.exports = { return _.map(settings, function (s) { return [ s.name, _.defaults(s, this.cmdDefaults(path)) ]; }.bind(this)); - }) + }.bind(this)) .then(_.zipObject) .then(function (targets) { if (_.isNull(this.activeTarget) || _.isUndefined(targets[this.activeTarget])) { @@ -242,26 +240,24 @@ module.exports = { }.bind(this)); return (this.targets = targets); - }); + }.bind(this)); }, selectActiveTarget: function() { var targetsView = new TargetsView(); targetsView.setLoading('Loading project build targets...\u2026'); - this.refreshTargets().bind(this).then(function (targets) { + this.refreshTargets().then(function (targets) { targetsView.setActiveTarget(this.activeTarget); targetsView.setItems(_.keys(targets)); return targetsView.awaitSelection(); - }).then(function(newTarget) { + }.bind(this)).then(function(newTarget) { this.activeTarget = newTarget; var workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); - }).catch(BuildError, function (error) { - targetsView.setError(error.message); - }).catch(function (error) { - targetsView.setError(error.message); + }.bind(this)).catch(function (err) { + targetsView.setError(err.message); }); }, @@ -302,10 +298,9 @@ module.exports = { this.match = []; Promise.resolve() - .bind(this) .then(function () { return (this.activeTarget) ? this.targets : this.refreshTargets(); - }) + }.bind(this)) .then(function (targets) { this.cmd = targets[targetName ? targetName : this.activeTarget]; GoogleAnalytics.sendEvent('build', 'triggered'); @@ -367,17 +362,19 @@ module.exports = { this.buildView.buildStarted(); this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ') + '\n'); - }).catch(BuildError, function (error) { - if (source === 'save') { - // If there is no eligible build tool, and cause of build was a save, stay quiet. - return; - } + }.bind(this)).catch(function (err) { + if (err instanceof BuildError) { + if (source === 'save') { + // If there is no eligible build tool, and cause of build was a save, stay quiet. + return; + } - atom.notifications.addError(error.name, { detail: error.message }); - }).catch(SyntaxError, function (error) { - atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + error.message }); - }).catch(function (error) { - atom.notifications.addError('Ooops. Something went wrong.', { detail: error.message + (error.stack ? '\n' + error.stack : '') }); + atom.notifications.addError(err.name, { detail: err.message }); + } else if (err instanceof SyntaxError) { + atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + err.message }); + } else { + atom.notifications.addError('Ooops. Something went wrong.', { detail: err.message + (err.stack ? '\n' + err.stack : '') }); + } }); }, diff --git a/lib/cscompatability.js b/lib/cscompatability.js index 3a3c0887..5179046f 100644 --- a/lib/cscompatability.js +++ b/lib/cscompatability.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; /* jshint newcap:false */ diff --git a/lib/error-matcher.js b/lib/error-matcher.js index c6440bbd..2ab4b484 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var fs = require('fs'); diff --git a/lib/google-analytics.js b/lib/google-analytics.js index e3ebb459..90c8474f 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var _ = require('lodash'); diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js index 4bd16fc6..f7e75a21 100644 --- a/lib/save-confirm-view.js +++ b/lib/save-confirm-view.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var View = require('atom-space-pen-views').View; diff --git a/lib/targets-view.js b/lib/targets-view.js index 43308cf6..9dcad24d 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -1,8 +1,8 @@ +'use babel'; 'use strict'; var SelectListView = require('atom-space-pen-views').SelectListView; var cscompatability = require('./cscompatability'); -var Promise = require('bluebird'); module.exports = (function() { function TargetsView() { diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js index 4492eb18..4c936c64 100644 --- a/lib/tools/Cargo.js +++ b/lib/tools/Cargo.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var fs = require('fs'); diff --git a/lib/tools/Elixir.js b/lib/tools/Elixir.js index 1e26e864..570f867f 100644 --- a/lib/tools/Elixir.js +++ b/lib/tools/Elixir.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var fs = require('fs'); diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 0896b629..5412774c 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var fs = require('fs'); @@ -5,7 +6,6 @@ var path = require('path'); var util = require('util'); var _ = require('lodash'); var Task = require('atom').Task; -var Promise = require('bluebird'); var originalNodePath = process.env.NODE_PATH; @@ -54,7 +54,8 @@ module.exports.settings = function (cwd) { return resolve(config); }); - }).finally(function () { + }).catch(function (err) { process.env.NODE_PATH = originalNodePath; + throw err; }); }; diff --git a/lib/tools/atom-build.js b/lib/tools/atom-build.js index 014174e1..0802cdfe 100644 --- a/lib/tools/atom-build.js +++ b/lib/tools/atom-build.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var path = require('path'); diff --git a/lib/tools/gulp-parser-task.js b/lib/tools/gulp-parser-task.js index f3cb1021..30f01644 100644 --- a/lib/tools/gulp-parser-task.js +++ b/lib/tools/gulp-parser-task.js @@ -24,7 +24,7 @@ module.exports = function (path) { window = undefined; /* jshint +W020 */ - require(path + '/gulpfile.js'); + require('./gulpfile.js'); return { tasks: Object.keys(gulp.tasks) }; } catch (e) { return { error: { message: e.message } }; diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index 94a1d3f3..e18b251c 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -5,7 +5,6 @@ var path = require('path'); var util = require('util'); var _ = require('lodash'); var Task = require('atom').Task; -var Promise = require('bluebird'); var originalNodePath = process.env.NODE_PATH; @@ -56,7 +55,8 @@ module.exports.settings = function (cwd) { return resolve(config); }); - }).finally(function () { + }).catch(function (err) { process.env.NODE_PATH = originalNodePath; + throw err; }); }; diff --git a/lib/tools/index.js b/lib/tools/index.js index 5771357b..2d498220 100644 --- a/lib/tools/index.js +++ b/lib/tools/index.js @@ -1,3 +1,6 @@ +'use babel'; +'use strict'; + /* Build tools available to atom-build. These are sorted in order of priority diff --git a/lib/tools/make.js b/lib/tools/make.js index 2a44ebf6..848c7e8b 100644 --- a/lib/tools/make.js +++ b/lib/tools/make.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var path = require('path'); diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index 1852550f..9216783a 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -1,3 +1,4 @@ +'use babel'; 'use strict'; var path = require('path'); diff --git a/package.json b/package.json index 11758652..b453f847 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,7 @@ "dependencies": { "ansi-to-html": "^0.3.0", "atom-space-pen-views": "^2.0.3", - "bluebird": "^2.9.25", - "fs-extra": "^0.18.3", + "fs-extra": "^0.23.0", "getmac": "^1.0.7", "lodash": "^3.8.0", "node-uuid": "^1.4.3", diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 9ba07e61..3cd92de5 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -1,10 +1,11 @@ +'use babel'; +'use strict'; + var _ = require('lodash'); var fs = require('fs-extra'); var temp = require('temp'); describe('Confirm', function() { - 'use strict'; - var goodMakefile = __dirname + '/fixture/Makefile.good'; var directory = null; diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index f61ff485..81c2c91c 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,9 +1,10 @@ +'use babel'; +'use strict'; + var fs = require('fs-extra'); var temp = require('temp'); describe('Error Match', function() { - 'use strict'; - var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; var errorMatchNoFileBuildFile = __dirname + '/fixture/.atom-build.error-match-no-file.json'; var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index 61cbd96a..d77a03a9 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -1,10 +1,11 @@ +'use babel'; +'use strict'; + var fs = require('fs-extra'); var temp = require('temp'); var specHelpers = require('./spec-helpers'); describe('Keymap', function() { - 'use strict'; - var directory = null; var workspaceElement = null; diff --git a/spec/build-spec.js b/spec/build-spec.js index 4e8ab4fe..9f92c675 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,9 +1,9 @@ +'use babel'; 'use strict'; var _ = require('lodash'); -var Promise = require('bluebird'); -var fs = Promise.promisifyAll(require('fs-extra')); -var temp = Promise.promisifyAll(require('temp')); +var fs = require('fs-extra'); +var temp = require('temp'); var specHelpers = require('./spec-helpers'); describe('Build', function() { @@ -42,8 +42,8 @@ describe('Build', function() { jasmine.unspy(window, 'clearTimeout'); waitsForPromise(function() { - return temp.mkdirAsync({ prefix: 'atom-build-spec-' }).then(function (dir) { - return fs.realpathAsync(dir); + return specHelpers.vouch(temp.mkdir, 'atom-build-spec-').then(function (dir) { + return specHelpers.vouch(fs.realpath, dir); }).then(function (dir) { directory = dir + '/'; atom.project.setPaths([ directory ]); @@ -53,7 +53,7 @@ describe('Build', function() { }); afterEach(function() { - fs.removeAsync(directory); + fs.removeSync(directory); }); describe('when package is activated', function() { diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 57ca7f9e..673f9314 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -1,12 +1,12 @@ +'use babel'; +'use strict'; + var _ = require('lodash'); -var Promise = require('bluebird'); -var fs = Promise.promisifyAll(require('fs-extra')); -var temp = Promise.promisifyAll(require('temp')); +var fs = require('fs-extra'); +var temp = require('temp'); var specHelpers = require('./spec-helpers'); describe('Target', function() { - 'use strict'; - var directory = null; var workspaceElement = null; @@ -24,8 +24,8 @@ describe('Target', function() { jasmine.attachToDOM(workspaceElement); waitsForPromise(function() { - return temp.mkdirAsync({ prefix: 'atom-build-spec-' }).then(function (dir) { - return fs.realpathAsync(dir); + return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then(function (dir) { + return specHelpers.vouch(fs.realpath, dir); }).then(function (dir) { directory = dir + '/'; atom.project.setPaths([ directory ]); @@ -35,7 +35,7 @@ describe('Target', function() { }); afterEach(function() { - fs.removeAsync(directory); + fs.removeSync(directory); }); describe('when multiple targets exists', function () { @@ -43,7 +43,7 @@ describe('Target', function() { it('should list those targets in a SelectListView (from .atom-build.json)', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return fs.copyAsync(file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); }); runs(function () { @@ -66,7 +66,7 @@ describe('Target', function() { waitsForPromise(function () { return Promise.resolve() .then(function () { - return fs.copyAsync(__dirname + '/fixture/Gruntfile.js', directory + '/Gruntfile.js'); + return specHelpers.vouch(fs.copy, __dirname + '/fixture/Gruntfile.js', directory + '/Gruntfile.js'); }) .then(specHelpers.setupNodeModules(directory)) .then(specHelpers.setupGrunt(directory)); @@ -88,11 +88,11 @@ describe('Target', function() { }); }); - it('should list those targets in a SelectListView (from gulpfile.js)', function () { + xit('should list those targets in a SelectListView (from gulpfile.js)', function () { waitsForPromise(function () { return Promise.resolve() .then(function () { - return fs.copyAsync(__dirname + '/fixture/gulpfile.js', directory + '/gulpfile.js'); + return specHelpers.vouch(fs.copy, __dirname + '/fixture/gulpfile.js', directory + '/gulpfile.js'); }) .then(specHelpers.setupNodeModules(directory)) .then(specHelpers.setupGulp(directory)); @@ -117,7 +117,7 @@ describe('Target', function() { it('should mark the first target as active', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return fs.copyAsync(file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); }); runs(function () { @@ -138,7 +138,7 @@ describe('Target', function() { it('should run the selected build', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return fs.copyAsync(file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); }); runs(function () { @@ -166,7 +166,7 @@ describe('Target', function() { it('should run the default target if no selection has been made', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return fs.copyAsync(file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); }); runs(function () { @@ -186,7 +186,7 @@ describe('Target', function() { it('run the selected target if selection has changed, and subsequent build should run that target', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return fs.copyAsync(file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); }); runs(function () { @@ -242,7 +242,7 @@ describe('Target', function() { it('should still list the default target for gulp', function () { waitsForPromise(function () { var file = __dirname + '/fixture/gulpfile.js'; - return fs.copyAsync(file, directory + '/gulpfile.js'); + return specHelpers.vouch(fs.copy, file, directory + '/gulpfile.js'); }); runs(function () { @@ -264,7 +264,7 @@ describe('Target', function() { it('should still list the default target for Grunt', function () { waitsForPromise(function () { var file = __dirname + '/fixture/Gruntfile.js'; - return fs.copyAsync(file, directory + '/Gruntfile.js'); + return specHelpers.vouch(fs.copy, file, directory + '/Gruntfile.js'); }); runs(function () { diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index fba14285..6b5cd8c9 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -1,9 +1,11 @@ -var Promise = require('bluebird'); -var fs = Promise.promisifyAll(require('fs-extra')); -var temp = Promise.promisifyAll(require('temp')); +'use babel'; +'use strict'; + +var fs = require('fs-extra'); +var temp = require('temp'); +var specHelpers = require('./spec-helpers'); describe('Visible', function() { - 'use strict'; var directory = null; var workspaceElement = null; @@ -28,8 +30,8 @@ describe('Visible', function() { }); waitsForPromise(function() { - return temp.mkdirAsync({ prefix: 'atom-build-spec-' }).then(function (dir) { - return fs.realpathAsync(dir); + return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then(function (dir) { + return specHelpers.vouch(fs.realpath, dir); }).then(function (dir) { directory = dir + '/'; atom.project.setPaths([ directory ]); @@ -37,6 +39,10 @@ describe('Visible', function() { }); }); + afterEach(function () { + fs.removeSync(directory); + }); + describe('when package is activated with panel visibility set to Keep Visible', function() { beforeEach(function () { atom.config.set('build.panelVisibility', 'Keep Visible'); diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js index a47c92f1..90adbaca 100644 --- a/spec/spec-helpers.js +++ b/spec/spec-helpers.js @@ -1,14 +1,14 @@ +'use babel'; 'use strict'; var path = require('path'); -var Promise = require('bluebird'); -var fs = Promise.promisifyAll(require('fs-extra')); +var fs = require('fs-extra'); module.exports = { setupNodeModules: function (directory) { return function () { - return fs.copyAsync(path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules')); - }; + return this.vouch(fs.copy, path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules')); + }.bind(this); }, setupGrunt: function (directory) { @@ -16,12 +16,12 @@ module.exports = { var realGrunt = path.join(directory, 'node_modules', 'grunt-cli', 'bin', 'grunt'); return function () { return Promise.all([ - fs.unlinkAsync(binGrunt), - fs.chmodAsync(realGrunt, parseInt('0700', 8)), + this.vouch(fs.unlink, binGrunt), + this.vouch(fs.chmod, realGrunt, parseInt('0700', 8)) ]).then(function () { - return fs.symlinkAsync(realGrunt, binGrunt); - }); - }; + return this.vouch(fs.symlink, realGrunt, binGrunt); + }.bind(this)); + }.bind(this); }, setupGulp: function (directory) { @@ -29,12 +29,12 @@ module.exports = { var realGulp = path.join(directory, 'node_modules', 'gulp', 'bin', 'gulp.js'); return function () { return Promise.all([ - fs.unlinkAsync(binGulp), - fs.chmodAsync(realGulp, parseInt('0700', 8)), + this.vouch(fs.unlink, binGulp), + this.vouch(fs.chmod, realGulp, parseInt('0700', 8)) ]).then(function () { - return fs.symlinkAsync(realGulp, binGulp); - }); - }; + return this.vouch(fs.symlink, realGulp, binGulp); + }.bind(this)); + }.bind(this); }, _dispatchKeyboardEvent: function (type, element, key, ctrl, alt, shift, meta) { @@ -70,5 +70,18 @@ module.exports = { this.dispatchKeyboardEvent(element, 'keydown', eventArgs); this.dispatchKeyboardEvent(element, 'keypress', eventArgs); this.dispatchKeyboardEvent(element, 'keyup', eventArgs); + }, + + vouch: function vouch(fn /* args... */) { + var args = Array.prototype.slice.call(arguments, 1); + return new Promise(function(resolve, reject) { + args.push(function(err, result) { + if (err) { + return reject(err); + } + resolve(result); + }); + fn.apply(null, args); + }); } }; From 4b6062e783ba681d798e2ff78854f7380ff428a6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 8 Aug 2015 09:48:18 +0200 Subject: [PATCH 137/495] BuildView: Optimized build title text loop --- lib/build-view.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 8e7f6f69..2b7e3ba0 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -11,13 +11,7 @@ var Convert = require('ansi-to-html'); module.exports = (function() { function BuildView() { View.apply(this, arguments); - this.titleLoop = [ - 'Building', - 'Building.', - 'Building..', - 'Building...' - ]; - this.titleLoopIndex = 0; + this.titleLoop = [ 'Building', 'Building.', 'Building..', 'Building...' ]; this.a2h = new Convert(); this.monocle = false; @@ -110,8 +104,8 @@ module.exports = (function() { }; BuildView.prototype.updateTitle = function() { - this.title.text(this.titleLoop[this.titleLoopIndex]); - this.titleLoopIndex = (this.titleLoopIndex + 1) % this.titleLoop.length; + this.title.text(this.titleLoop[0]); + this.titleLoop.push(this.titleLoop.shift()); this.titleTimer = setTimeout(this.updateTitle.bind(this), 200); }; From 68395522ba6442ca2dbd9b9b864aea769dc3ed43 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 10 Aug 2015 20:52:04 +0200 Subject: [PATCH 138/495] Show a warning rather than error on no tool If no tool can build the current project, show a warning rather than an error with a fire symbol. It's not *that* bad. --- lib/build.js | 2 +- spec/build-spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 43ea0d88..050b139b 100644 --- a/lib/build.js +++ b/lib/build.js @@ -369,7 +369,7 @@ module.exports = { return; } - atom.notifications.addError(err.name, { detail: err.message }); + atom.notifications.addWarning(err.name, { detail: err.message }); } else if (err instanceof SyntaxError) { atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + err.message }); } else { diff --git a/spec/build-spec.js b/spec/build-spec.js index 9f92c675..2f8e1a3a 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -806,7 +806,7 @@ describe('Build', function() { }); describe('when no build tools are available', function () { - it('should show an error', function () { + it('should show a warning', function () { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.commands.dispatch(workspaceElement, 'build:trigger'); @@ -816,7 +816,7 @@ describe('Build', function() { runs(function() { var notification = atom.notifications.getNotifications()[0]; - expect(notification.getType()).toEqual('error'); + expect(notification.getType()).toEqual('warning'); expect(notification.getMessage()).toEqual('No eligible build tool.'); }); }); From efaac6598e6bb3897c9525ef26e44497854f5a13 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 10 Aug 2015 21:07:45 +0200 Subject: [PATCH 139/495] moved array detectin logic to errorMatcher --- lib/build.js | 6 +----- lib/error-matcher.js | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/build.js b/lib/build.js index e67812eb..14db6673 100644 --- a/lib/build.js +++ b/lib/build.js @@ -361,11 +361,7 @@ module.exports = { }.bind(this), 1000); } else { var t = this.targets[this.activeTarget]; - var errorMatch = t.errorMatch; - if (!(errorMatch instanceof Array)) { - errorMatch = [errorMatch]; - } - this.errorMatcher.set(errorMatch, this.replace(t.cwd), this.buildView.output.text()); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); if (atom.config.get('build.scrollOnError')) { this.errorMatcher.matchFirst(); } diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 46cb506f..080d3f34 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -90,6 +90,8 @@ module.exports = (function () { }; ErrorMatcher.prototype.set = function (regex, cwd, output) { + regex = (regex instanceof Array) ? regex : [ regex ]; + this.regex = []; for (var i in regex) { var curRegex = null; From a8c522af9b2c6d5202544e3b5582f4fa7823e954 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 10 Aug 2015 21:18:13 +0200 Subject: [PATCH 140/495] use more lodash --- lib/error-matcher.js | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 080d3f34..4dc93830 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -92,21 +92,14 @@ module.exports = (function () { ErrorMatcher.prototype.set = function (regex, cwd, output) { regex = (regex instanceof Array) ? regex : [ regex ]; - this.regex = []; - for (var i in regex) { - var curRegex = null; + this.regex = _.compact(regex.map(function(r) { try { - curRegex = XRegExp(regex[i]); + return XRegExp(r); } catch (err) { this.emit('error', 'Error parsing regex:\n' + err); + return null; } - if (curRegex !== null) { - this.regex.push(curRegex); - } - } - if (this.regex.length === 0) { - this.regex = 0; - } + })); this.cwd = cwd; this.output = output; @@ -114,10 +107,6 @@ module.exports = (function () { }; ErrorMatcher.prototype.match = function () { - if (!this.regex) { - return; - } - GoogleAnalytics.sendEvent('errorMatch', 'match'); if (0 === this.currentMatch.length && 0 === this._parse()) { @@ -128,10 +117,6 @@ module.exports = (function () { }; ErrorMatcher.prototype.matchFirst = function () { - if (!this.regex) { - return; - } - GoogleAnalytics.sendEvent('errorMatch', 'first'); if (0 === this._parse()) { From 05a306ee7c7c31485a9c6cea9ae20940e8c0246b Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 10 Aug 2015 21:29:38 +0200 Subject: [PATCH 141/495] added info to readme.md --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8bed8dfd..dcac6e7b 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,10 @@ exactly what to execute. Create a file named `.atom-build.json` in your project "VARIABLE2": "VALUE2", ... }, - "errorMatch": "^regexp$", + "errorMatch": [ + "^regexp1$", + "^regexp2$" + ] "keymap": "", "targets": { "": { @@ -78,7 +81,7 @@ systems). * `sh` - **[optional]** If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. * `cwd` - **[optional]** The working directory for the command. E.g. what `.` resolves to. * `env` - **[optional]** An object of environment variables and their values to set - * `errorMatch` - **[optional]** A regular expression to match output to a file, row and col. See [Error matching](#error-match) for details. + * `errorMatch` - **[optional]** A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. * `keymap` - **[optional]** A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. * `targets`- **[optional]** Additional targets which can be used to build variations of your project. @@ -97,9 +100,9 @@ values of `env`. They should all be enclosed in curly brackets `{}` ## Error matching -Error matching let's you specify a regular expression which captures -the output of your build command and opens the correct file, row and column of -the error. For instance: +Error matching let's you specify a single regular expression or a list of +regular expressions, which capture the output of your build command and open the +correct file, row and column of the error. For instance: ```bash a.c:4:26: error: expected ';' after expression @@ -122,7 +125,7 @@ The following named groups can be matched from the output: * `line` - **[optional]** the line the error resides on. `(? RE)`. * `col` - **[optional]** the column the error resides on. `(? RE)`. -Since the regular expression is written in a JSON file, backslashes must be escaped. +Since the regular expressions are written in a JSON file, backslashes must be escaped. The `file` should be relative the `cwd` specified. If no `cwd` has been specified, then the `file` should be relative the project root (e.g. the top most directory shown in the From 5f9b516bafe875d44926cee6facaf097f195cf25 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 10 Aug 2015 21:43:36 +0200 Subject: [PATCH 142/495] added spec --- spec/build-error-match-spec.js | 63 +++++++++++++++++++ ...build.error-match-multiple-errorMatch.json | 7 +++ 2 files changed, 70 insertions(+) create mode 100755 spec/fixture/.atom-build.error-match-multiple-errorMatch.json diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 4fde658e..276955c9 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -9,6 +9,7 @@ describe('Error Match', function() { var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; var errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json'; var errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; + var errorMatchMultiMatcherAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-errorMatch.json'; var directory = null; var workspaceElement = null; @@ -321,5 +322,67 @@ describe('Error Match', function() { expect(notification.options.detail).toMatch(/Unterminated group/); }); }); + + it('should match multiple regexes in the correct order', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiMatcherAtomBuildFile)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(2); + expect(bufferPosition.column).toEqual(7); + atom.workspace.getActivePane().destroyActiveItem(); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(0); + expect(bufferPosition.column).toEqual(1); + atom.workspace.getActivePane().destroyActiveItem(); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:error-match'); + }); + + waitsFor(function() { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function() { + var editor = atom.workspace.getActiveTextEditor(); + var bufferPosition = editor.getCursorBufferPosition(); + expect(editor.getTitle()).toEqual('.atom-build.json'); + expect(bufferPosition.row).toEqual(1); + expect(bufferPosition.column).toEqual(4); + }); + }); }); }); diff --git a/spec/fixture/.atom-build.error-match-multiple-errorMatch.json b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json new file mode 100755 index 00000000..37bab629 --- /dev/null +++ b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json @@ -0,0 +1,7 @@ +{ + "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:1,column::::2'\nfile:.atom-build.json,line:2,column:5' && return 1", + "errorMatch": [ + "file:(?[^,]+),line:(?\\d+),column:(?\\d+)", + "file:(?[^,]+),line:(?\\d+),column::::(?\\d+)" + ] +} From 50320854401e6ec9610ff699ddf1dbfb6fe1338d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 12 Aug 2015 19:39:06 +0200 Subject: [PATCH 143/495] ErrorMatch: codestyle and test fix --- lib/error-matcher.js | 4 ++-- .../.atom-build.error-match-multiple-errorMatch.json | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 614fa4f6..4d1507f7 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -97,10 +97,10 @@ module.exports = (function () { try { return XRegExp(r); } catch (err) { - this.emit('error', 'Error parsing regex:\n' + err); + this.emit('error', 'Error parsing regex. ' + err.message); return null; } - })); + }.bind(this))); this.cwd = cwd; this.output = output; diff --git a/spec/fixture/.atom-build.error-match-multiple-errorMatch.json b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json index 37bab629..8f6aa14f 100755 --- a/spec/fixture/.atom-build.error-match-multiple-errorMatch.json +++ b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json @@ -1,7 +1,7 @@ { - "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:1,column::::2'\nfile:.atom-build.json,line:2,column:5' && return 1", - "errorMatch": [ - "file:(?[^,]+),line:(?\\d+),column:(?\\d+)", - "file:(?[^,]+),line:(?\\d+),column::::(?\\d+)" - ] + "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:1,column::::2'\nfile:.atom-build.json,line:2,column:5' && return 1", + "errorMatch": [ + "file:(?[^,]+),line:(?\\d+),column:(?\\d+)", + "file:(?[^,]+),line:(?\\d+),column::::(?\\d+)" + ] } From 43d528ec32c768508c7d23f70bc99cc69c4d9dac Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 12 Aug 2015 20:31:29 +0200 Subject: [PATCH 144/495] BuildView: Line-buffer output. Line buffer the output in the build panel so that each row from the build command (as determined by the platform specific EOL) gets each own row, rather than just giving a row to whatever chunk of data comes on the pipe. Fixes #148 --- lib/build-view.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 2b7e3ba0..96eeed13 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -14,6 +14,7 @@ module.exports = (function() { this.titleLoop = [ 'Building', 'Building.', 'Building..', 'Building...' ]; this.a2h = new Convert(); this.monocle = false; + this.buffer = new Buffer(0); atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this)); @@ -160,6 +161,7 @@ module.exports = (function() { } this.title.text(success ? 'Build finished.' : 'Build failed.'); this.title.addClass(success ? 'success' : 'error'); + this.append(new Buffer(0), true); clearTimeout(this.titleTimer); }; @@ -171,11 +173,22 @@ module.exports = (function() { BuildView.prototype.buildAborted = function() { this.title.text('Aborted!'); + this.append(new Buffer(0), true); }; - BuildView.prototype.append = function(line) { - line = _.escape(line.toString()); - this.output.append('
  • ' + (this.a2h.toHtml(line)) + '
  • '); + BuildView.prototype.append = function(data, force) { + data = Buffer.isBuffer(data) ? data : new Buffer(data); + force = force || false; + + this.buffer = Buffer.concat([ this.buffer, data ]); + var bufferedString = this.buffer.toString(); + if (!force && -1 === bufferedString.indexOf(require('os').EOL)) { + /* No line break in output. Don't do anything */ + return; + } + + this.buffer = new Buffer(0); + this.output.append('
  • ' + this.a2h.toHtml(_.escape(bufferedString)) + '
  • '); this.output.scrollTop(this.output[0].scrollHeight); }; From cfc2225965f1ca8a8f76d9b2378baece6cdfd74f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 12 Aug 2015 20:51:01 +0200 Subject: [PATCH 145/495] Build view specs Tests to make sure build view behaves as expected. --- lib/build-view.js | 4 +- spec/build-spec.js | 20 ------- spec/build-view-spec.js | 116 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 22 deletions(-) create mode 100644 spec/build-view-spec.js diff --git a/lib/build-view.js b/lib/build-view.js index 96eeed13..b0a48a8a 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -182,8 +182,8 @@ module.exports = (function() { this.buffer = Buffer.concat([ this.buffer, data ]); var bufferedString = this.buffer.toString(); - if (!force && -1 === bufferedString.indexOf(require('os').EOL)) { - /* No line break in output. Don't do anything */ + if (0 === bufferedString.length || (!force && -1 === bufferedString.indexOf(require('os').EOL))) { + /* No line break in output or no output at all. Don't do anything */ return; } diff --git a/spec/build-spec.js b/spec/build-spec.js index 2f8e1a3a..1dfee05e 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -10,7 +10,6 @@ describe('Build', function() { var goodMakefile = __dirname + '/fixture/Makefile.good'; var badMakefile = __dirname + '/fixture/Makefile.bad'; var longMakefile = __dirname + '/fixture/Makefile.long'; - var escapeMakefile = __dirname + '/fixture/Makefile.escape'; var goodGruntfile = __dirname + '/fixture/Gruntfile.js'; var goodGulpfile = __dirname + '/fixture/gulpfile.js'; var goodNodefile = __dirname + '/fixture/package.json.node'; @@ -647,25 +646,6 @@ describe('Build', function() { }); }); - describe('when output from build contains HTML characters', function() { - it('should escape those properly so the output is not garbled or missing', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(escapeMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/<script type="text\/javascript">alert\('XSS!'\)<\/script>/); - }); - }); - }); - describe('when the text editor is saved', function() { it('should build when buildOnSave is true', function() { atom.config.set('build.buildOnSave', true); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js new file mode 100644 index 00000000..c8b403a1 --- /dev/null +++ b/spec/build-view-spec.js @@ -0,0 +1,116 @@ +'use babel'; +'use strict'; + +var fs = require('fs-extra'); +var temp = require('temp'); +var specHelpers = require('./spec-helpers'); + +describe('Visible', function() { + + var directory = null; + var workspaceElement = null; + + temp.track(); + + beforeEach(function() { + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + atom.config.set('build.stealFocus', true); + atom.notifications.clear(); + + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + + runs(function() { + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + }); + + waitsForPromise(function() { + return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then(function (dir) { + return specHelpers.vouch(fs.realpath, dir); + }).then(function (dir) { + directory = dir + '/'; + atom.project.setPaths([ directory ]); + return atom.packages.activatePackage('build'); + }); + }); + }); + + afterEach(function () { + fs.removeSync(directory); + }); + + describe('when output from build command should be viewed', function() { + it('should color output according to ansi escape codes', function () { + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'printf "\\033[31mHello\\e[0m World"' + })); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build ol.output > li > span').style.color.match(/\d+/g)).toEqual([ '170', '0', '0' ]); + }); + }); + + it('should output data even if no line break exists', function () { + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'printf "data without linebreak"' + })); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/data without linebreak/); + }); + }); + + it('should only break the line when an actual newline character appears', function () { + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'node -e \'process.stdout.write("same"); setTimeout(function () { process.stdout.write(" line\\n") }, 200);\'' + })); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function () { + /* Now we expect one line for the 'Executing...' row. And one for the actual output. */ + var el = workspaceElement.querySelector('.build .output'); + expect(el.childElementCount).toEqual(2); + expect(el.querySelector('li:nth-child(2)').textContent).toEqual('same line\n'); + }); + }); + + it('should escape HTML chars so the output is not garbled or missing', function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.escape')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/<script type="text\/javascript">alert\('XSS!'\)<\/script>/); + }); + }); + }); +}); From 65c8eafb71c7e748270069bdb866015346993495 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 14 Aug 2015 10:52:46 +0200 Subject: [PATCH 146/495] README: Make optional entries stand out less --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 59a0e99c..609d4814 100644 --- a/README.md +++ b/README.md @@ -76,14 +76,14 @@ systems). ### Configuration options * `cmd` - **[required]** The executable command - * `name` - **[optional]** The name of the targets. Viewed in the targets list (toggled by `build:select-active-target`). - * `args` - **[optional]** An array of arguments for the command - * `sh` - **[optional]** If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. - * `cwd` - **[optional]** The working directory for the command. E.g. what `.` resolves to. - * `env` - **[optional]** An object of environment variables and their values to set - * `errorMatch` - **[optional]** A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. - * `keymap` - **[optional]** A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. - * `targets`- **[optional]** Additional targets which can be used to build variations of your project. + * `name` - *[optional]* The name of the targets. Viewed in the targets list (toggled by `build:select-active-target`). + * `args` - *[optional]* An array of arguments for the command + * `sh` - *[optional]* If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. + * `cwd` - *[optional]* The working directory for the command. E.g. what `.` resolves to. + * `env` - *[optional]* An object of environment variables and their values to set + * `errorMatch` - *[optional]* A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. + * `keymap` - *[optional]* A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. + * `targets`- *[optional]* Additional targets which can be used to build variations of your project. ### Replacements @@ -122,8 +122,8 @@ matched by the regular expression `RE`. The following named groups can be matched from the output: * `file` - **[required]** the file to open. May be relative `cwd` or absolute. `(? RE)`. - * `line` - **[optional]** the line the error resides on. `(? RE)`. - * `col` - **[optional]** the column the error resides on. `(? RE)`. + * `line` - *[optional]* the line the error resides on. `(? RE)`. + * `col` - *[optional]* the column the error resides on. `(? RE)`. Since the regular expressions are written in a JSON file, backslashes must be escaped. From 8c69e78b7ca226bdc631e9e85e2c9e315ed862c9 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 14 Aug 2015 11:02:28 +0200 Subject: [PATCH 147/495] README: Use a table for build options For better readability --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 609d4814..f99efa1a 100644 --- a/README.md +++ b/README.md @@ -75,15 +75,17 @@ systems). ### Configuration options - * `cmd` - **[required]** The executable command - * `name` - *[optional]* The name of the targets. Viewed in the targets list (toggled by `build:select-active-target`). - * `args` - *[optional]* An array of arguments for the command - * `sh` - *[optional]* If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. - * `cwd` - *[optional]* The working directory for the command. E.g. what `.` resolves to. - * `env` - *[optional]* An object of environment variables and their values to set - * `errorMatch` - *[optional]* A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. - * `keymap` - *[optional]* A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. - * `targets`- *[optional]* Additional targets which can be used to build variations of your project. +Option | Required | Description +-------------|----------------|----------------------- +`cmd` | **[required]** | The executable command +`name` | *[optional]* | The name of the targets. Viewed in the targets list (toggled by `build:select-active-target`). +`args` | *[optional]* | An array of arguments for the command +`sh` | *[optional]* | If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. +`cwd` | *[optional]* | The working directory for the command. E.g. what `.` resolves to. +`env` | *[optional]* | An object of environment variables and their values to set +`errorMatch` | *[optional]* | A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. +`keymap` | *[optional]* | A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. +`targets` | *[optional]* | Additional targets which can be used to build variations of your project. ### Replacements From 4b06a5852712e03c91c43b4153896433f20fd3e6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 15 Aug 2015 01:01:32 +0200 Subject: [PATCH 148/495] BuildView: Include a timer Timer helps keep track of the time builds take. It also gives a sense that stuff is happening. --- lib/build-view.js | 33 ++++++++++++++++++++++----------- spec/build-spec.js | 2 +- spec/build-view-spec.js | 21 +++++++++++++++++++++ styles/build.less | 12 +++++++++--- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index b0a48a8a..260363cb 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -12,9 +12,15 @@ module.exports = (function() { function BuildView() { View.apply(this, arguments); this.titleLoop = [ 'Building', 'Building.', 'Building..', 'Building...' ]; + this.titleLoop.rotate = function () { + /* Throttle as we don't want to update as quick as the timer is */ + this.n = this.n || 0; + (++this.n === 3) && this.push(this.shift()) && (this.n = 0); + }; this.a2h = new Convert(); this.monocle = false; this.buffer = new Buffer(0); + this.starttime = new Date(); atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this)); @@ -28,10 +34,10 @@ module.exports = (function() { BuildView.content = function() { BuildView.div({ tabIndex: -1, class: 'build tool-panel panel-bottom native-key-bindings' }, function() { BuildView.div({ class: 'btn-container pull-right' }, function() { - BuildView.button({ class: 'btn btn-default icon icon-x', outlet: 'closeButton', click: 'close' }); + BuildView.button({ class: 'btn btn-default icon icon-x', click: 'close' }); BuildView.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' }); - BuildView.button({ class: 'btn btn-default icon icon-trashcan new-row', outlet: 'clearButton', click: 'clear' }); - BuildView.button({ class: 'btn btn-default icon icon-zap', outlet: 'triggerButton', click: 'build', title: 'Build current project' }); + BuildView.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clear' }); + BuildView.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' }); }); BuildView.div(function() { @@ -39,7 +45,10 @@ module.exports = (function() { }); BuildView.div(function() { - BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, 'Ready'); + BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, function () { + BuildView.span({ class: 'build-timer', outlet: 'buildTimer' }, '0.0 s'); + BuildView.span({ class: 'title-text', outlet: 'titleText' }, 'Ready'); + }); }); }); }; @@ -100,14 +109,15 @@ module.exports = (function() { this.titleTimer = 0; this.title.removeClass('success error warning'); this.output.empty(); - this.title.text('Cleared.'); + this.titleText.text('Cleared.'); this.detach(); }; BuildView.prototype.updateTitle = function() { - this.title.text(this.titleLoop[0]); - this.titleLoop.push(this.titleLoop.shift()); - this.titleTimer = setTimeout(this.updateTitle.bind(this), 200); + this.titleText.text(this.titleLoop[0]); + this.titleLoop.rotate(); + this.buildTimer.text(((new Date() - this.starttime) / 1000).toFixed(1) + ' s'); + this.titleTimer = setTimeout(this.updateTitle.bind(this), 100); }; BuildView.prototype.close = function(event, element) { @@ -146,6 +156,7 @@ module.exports = (function() { }; BuildView.prototype.buildStarted = function() { + this.starttime = new Date(); this.reset(); this.attach(); if (atom.config.get('build.stealFocus')) { @@ -159,20 +170,20 @@ module.exports = (function() { var force = (atom.config.get('build.panelVisibility') === 'Show on Error'); this.attach(force); } - this.title.text(success ? 'Build finished.' : 'Build failed.'); + this.titleText.text(success ? 'Build finished.' : 'Build failed.'); this.title.addClass(success ? 'success' : 'error'); this.append(new Buffer(0), true); clearTimeout(this.titleTimer); }; BuildView.prototype.buildAbortInitiated = function() { - this.title.text('Build process termination imminent...'); + this.titleText.text('Build process termination imminent...'); clearTimeout(this.titleTimer); this.title.addClass('error'); }; BuildView.prototype.buildAborted = function() { - this.title.text('Aborted!'); + this.titleText.text('Aborted!'); this.append(new Buffer(0), true); }; diff --git a/spec/build-spec.js b/spec/build-spec.js index 1dfee05e..bcf81243 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -161,7 +161,7 @@ describe('Build', function() { }); waitsFor(function() { - return (workspaceElement.querySelector('.build .title').textContent == 'Aborted!'); + return (workspaceElement.querySelector('.build .title .title-text').textContent == 'Aborted!'); }); }); }); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index c8b403a1..3cbf357f 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -113,4 +113,25 @@ describe('Visible', function() { }); }); }); + + describe('when a build is triggered', function () { + it('should include a timer of the build', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.long')); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + // Let build run for 1.2 second. This should set the timer at "at least" 1.2 + // which is expected below. If this waits longer than 2000 ms, we're in trouble. + waits(1200); + + runs(function() { + expect(workspaceElement.querySelector('.build-timer').textContent).toMatch(/1.\d/); + + // stop twice to abort the build + atom.commands.dispatch(workspaceElement, 'build:stop'); + atom.commands.dispatch(workspaceElement, 'build:stop'); + }); + }); + }); }); diff --git a/styles/build.less b/styles/build.less index b16fb41e..cc8f7920 100644 --- a/styles/build.less +++ b/styles/build.less @@ -1,19 +1,25 @@ @import "ui-variables"; .build { - h1.error { + .build-timer { + display: inline-block; + width: 5em; + margin-right: 10px; + } + + .title.error { color: white; background-image: none; background-color: @background-color-error; } - h1.success { + .title.success { color: white; background-image: none; background-color: @background-color-success; } - h1.warning { + .title.warning { color: white; background-image:none; background-color: @background-color-warning; From fd9b0d7aadb2a22b26a77fe5e6354780d07462d2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 15 Aug 2015 01:20:01 +0200 Subject: [PATCH 149/495] BuildView: Transition outcome color Because it's neat. And easy. --- styles/build.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/styles/build.less b/styles/build.less index cc8f7920..e8e78bd0 100644 --- a/styles/build.less +++ b/styles/build.less @@ -1,6 +1,10 @@ @import "ui-variables"; .build { + .title { + transition: background-color 0.2s ease-in; + } + .build-timer { display: inline-block; width: 5em; From 7efe773a873c480dddbfb6e6344034526cae6f36 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 15 Aug 2015 10:45:32 +0200 Subject: [PATCH 150/495] reverted scroll remove --- lib/build-view.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/build-view.js b/lib/build-view.js index c75d1575..260363cb 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -209,6 +209,7 @@ module.exports = (function() { this.output.find('a').on('click', function() { onclick($(this).attr('id')); }); + this.output.scrollTop(this.output[0].scrollHeight); }; BuildView.prototype.scrollTo = function(type, id) { From cd60eb42681eff6cb0f48e28ec8f283a7a7c5cd6 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 15 Aug 2015 12:27:17 +0200 Subject: [PATCH 151/495] not all windows programs use \r\n --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 260363cb..e0e1080a 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -193,7 +193,7 @@ module.exports = (function() { this.buffer = Buffer.concat([ this.buffer, data ]); var bufferedString = this.buffer.toString(); - if (0 === bufferedString.length || (!force && -1 === bufferedString.indexOf(require('os').EOL))) { + if (0 === bufferedString.length || (!force && -1 === bufferedString.indexOf('\n'))) { /* No line break in output or no output at all. Don't do anything */ return; } From 55ed239d392d9217db538a8633dbb1155f0a63ec Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 15 Aug 2015 12:39:34 +0200 Subject: [PATCH 152/495] flush buffer on reading output --- lib/build-view.js | 5 +++++ lib/build.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 260363cb..734d1016 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -219,5 +219,10 @@ module.exports = (function() { } }; + BuildView.prototype.getOutput = function() { + this.append(new Buffer(0), true); + return this.output.text(); + }; + return BuildView; })(); diff --git a/lib/build.js b/lib/build.js index c7da33b3..a9d2a526 100644 --- a/lib/build.js +++ b/lib/build.js @@ -344,7 +344,7 @@ module.exports = { this.child.on('close', function(exitCode) { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.getOutput()); var success = 0 === exitCode && !this.errorMatcher.hasMatch(); this.buildView.buildFinished(success); From efde5260f68e0fa3fcafa797bb22623882dcbdec Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 15 Aug 2015 16:41:37 +0200 Subject: [PATCH 153/495] Prepare 0.44.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b453f847..dfc4e497 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.43.0", + "version": "0.44.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 5bc2904fdff599e75e2c266ea0f7410057cc6b57 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sat, 15 Aug 2015 17:05:08 +0200 Subject: [PATCH 154/495] emit instead of throw --- lib/error-matcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 1bd6bba9..3dc27163 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -36,7 +36,7 @@ module.exports = (function () { ErrorMatcher.prototype._goto = function (id) { var match = _.findWhere(this.currentMatch, { id: id }); if (!match) { - throw new Error('Can\'t find match with id ' + id); + return this.emit('error', 'Can\'t find match with id ' + id); } // rotate to next match From 3668b7bba23fd6223f642becb63a6541ca473a3a Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Tue, 18 Aug 2015 14:15:06 +0200 Subject: [PATCH 155/495] removed buffering --- lib/build-view.js | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index e0e1080a..185fa2e1 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -19,7 +19,6 @@ module.exports = (function() { }; this.a2h = new Convert(); this.monocle = false; - this.buffer = new Buffer(0); this.starttime = new Date(); atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); @@ -41,7 +40,9 @@ module.exports = (function() { }); BuildView.div(function() { - BuildView.ol({ class: 'output panel-body', outlet: 'output' }); + BuildView.ol({ class: 'output panel-body', outlet: 'output' }, function() { + BuildView.li({ outlet: 'outputContent' }); + }); }); BuildView.div(function() { @@ -108,7 +109,7 @@ module.exports = (function() { clearTimeout(this.titleTimer); this.titleTimer = 0; this.title.removeClass('success error warning'); - this.output.empty(); + this.outputContent.empty(); this.titleText.text('Cleared.'); this.detach(); }; @@ -172,7 +173,6 @@ module.exports = (function() { } this.titleText.text(success ? 'Build finished.' : 'Build failed.'); this.title.addClass(success ? 'success' : 'error'); - this.append(new Buffer(0), true); clearTimeout(this.titleTimer); }; @@ -184,28 +184,16 @@ module.exports = (function() { BuildView.prototype.buildAborted = function() { this.titleText.text('Aborted!'); - this.append(new Buffer(0), true); }; BuildView.prototype.append = function(data, force) { - data = Buffer.isBuffer(data) ? data : new Buffer(data); - force = force || false; - - this.buffer = Buffer.concat([ this.buffer, data ]); - var bufferedString = this.buffer.toString(); - if (0 === bufferedString.length || (!force && -1 === bufferedString.indexOf('\n'))) { - /* No line break in output or no output at all. Don't do anything */ - return; - } - - this.buffer = new Buffer(0); - this.output.append('
  • ' + this.a2h.toHtml(_.escape(bufferedString)) + '
  • '); + this.outputContent.append(this.a2h.toHtml(_.escape(data))); this.output.scrollTop(this.output[0].scrollHeight); }; BuildView.prototype.replace = function(text, onclick) { - this.output.empty(); - this.output.append('
  • ' + (this.a2h.toHtml(text)) + '
  • '); + this.outputContent.empty(); + this.outputContent.append(this.a2h.toHtml(text)); this.output.find('a').on('click', function() { onclick($(this).attr('id')); }); From 226645a74a4cd74a99e0ed48b0ca09bb799cbfa3 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Tue, 18 Aug 2015 14:28:38 +0200 Subject: [PATCH 156/495] removed force param --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 185fa2e1..faba5b99 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -186,7 +186,7 @@ module.exports = (function() { this.titleText.text('Aborted!'); }; - BuildView.prototype.append = function(data, force) { + BuildView.prototype.append = function(data) { this.outputContent.append(this.a2h.toHtml(_.escape(data))); this.output.scrollTop(this.output[0].scrollHeight); }; From 2a2b2749aa2ed3b0d51b0cb29441f3b23a04b5ec Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Tue, 18 Aug 2015 15:00:29 +0200 Subject: [PATCH 157/495] fixed testcase --- spec/build-view-spec.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 3cbf357f..ff7a76f1 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -89,10 +89,12 @@ describe('Visible', function() { }); runs(function () { - /* Now we expect one line for the 'Executing...' row. And one for the actual output. */ var el = workspaceElement.querySelector('.build .output'); - expect(el.childElementCount).toEqual(2); - expect(el.querySelector('li:nth-child(2)').textContent).toEqual('same line\n'); + expect(el.childElementCount).toEqual(1); + /* Now we expect one line for the 'Executing...' row, one for the actual output and an empty one at the end. */ + var lines = el.querySelector('li').textContent.split('\n'); + expect(lines.length).toEqual(3); + expect(lines[1]).toEqual('same line'); }); }); From e21bf408041aa443fb01757b499072d6156a7da2 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Wed, 19 Aug 2015 10:21:52 +0200 Subject: [PATCH 158/495] fixed gulp targets? --- lib/tools/gulp-parser-task.js | 2 +- spec/build-targets-spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tools/gulp-parser-task.js b/lib/tools/gulp-parser-task.js index 30f01644..f3cb1021 100644 --- a/lib/tools/gulp-parser-task.js +++ b/lib/tools/gulp-parser-task.js @@ -24,7 +24,7 @@ module.exports = function (path) { window = undefined; /* jshint +W020 */ - require('./gulpfile.js'); + require(path + '/gulpfile.js'); return { tasks: Object.keys(gulp.tasks) }; } catch (e) { return { error: { message: e.message } }; diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 673f9314..72f1ea52 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -88,7 +88,7 @@ describe('Target', function() { }); }); - xit('should list those targets in a SelectListView (from gulpfile.js)', function () { + it('should list those targets in a SelectListView (from gulpfile.js)', function () { waitsForPromise(function () { return Promise.resolve() .then(function () { From ccf3b04dc232c05e5bac9680f5001c2bae66788e Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 20 Aug 2015 19:58:16 +0200 Subject: [PATCH 159/495] BuildView: Simplify panel There's no need for the ordered list anymore. --- lib/build-view.js | 14 +++++--------- spec/build-view-spec.js | 5 ++--- styles/build.less | 12 +----------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index faba5b99..02148d3a 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -39,11 +39,7 @@ module.exports = (function() { BuildView.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' }); }); - BuildView.div(function() { - BuildView.ol({ class: 'output panel-body', outlet: 'output' }, function() { - BuildView.li({ outlet: 'outputContent' }); - }); - }); + BuildView.div({ class: 'output panel-body', outlet: 'output' }); BuildView.div(function() { BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, function () { @@ -109,7 +105,7 @@ module.exports = (function() { clearTimeout(this.titleTimer); this.titleTimer = 0; this.title.removeClass('success error warning'); - this.outputContent.empty(); + this.output.empty(); this.titleText.text('Cleared.'); this.detach(); }; @@ -187,13 +183,13 @@ module.exports = (function() { }; BuildView.prototype.append = function(data) { - this.outputContent.append(this.a2h.toHtml(_.escape(data))); + this.output.append(this.a2h.toHtml(_.escape(data))); this.output.scrollTop(this.output[0].scrollHeight); }; BuildView.prototype.replace = function(text, onclick) { - this.outputContent.empty(); - this.outputContent.append(this.a2h.toHtml(text)); + this.output.empty(); + this.output.append(this.a2h.toHtml(text)); this.output.find('a').on('click', function() { onclick($(this).attr('id')); }); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index ff7a76f1..05150b5e 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -57,7 +57,7 @@ describe('Visible', function() { }); runs(function () { - expect(workspaceElement.querySelector('.build ol.output > li > span').style.color.match(/\d+/g)).toEqual([ '170', '0', '0' ]); + expect(workspaceElement.querySelector('.build .output > span').style.color.match(/\d+/g)).toEqual([ '170', '0', '0' ]); }); }); @@ -90,9 +90,8 @@ describe('Visible', function() { runs(function () { var el = workspaceElement.querySelector('.build .output'); - expect(el.childElementCount).toEqual(1); /* Now we expect one line for the 'Executing...' row, one for the actual output and an empty one at the end. */ - var lines = el.querySelector('li').textContent.split('\n'); + var lines = el.textContent.split('\n'); expect(lines.length).toEqual(3); expect(lines[1]).toEqual('same line'); }); diff --git a/styles/build.less b/styles/build.less index e8e78bd0..c7894a8b 100644 --- a/styles/build.less +++ b/styles/build.less @@ -29,26 +29,16 @@ background-color: @background-color-warning; } - ol { + .output { transition: height 0.5s ease-in-out; padding: 10px 0 0 10px; min-height: 100px; overflow-y: auto; - } - - li { word-wrap: break-word; white-space: pre-wrap; list-style: none; font-family: monospace; } - - li.error { - animation: none; - -webkit-animation: none; - color: @text-color-error; - } - } .btn-container { From 35997567386a482ce385b032f0ed067104387523 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 23 Aug 2015 20:25:48 +0200 Subject: [PATCH 160/495] Improved intra-process communication The interfaces between `build`, `error-matcher` and `build-view` is improved to decouple the modules. `error-matcher` no longer have any knowledge of how the matching it performs is actually used, and `build-view` no longer knows what the links it creates are used for. All together: better design. --- lib/build-view.js | 36 ++++++++++++++++++++++++++---------- lib/build.js | 10 ++++++++-- lib/error-matcher.js | 31 ++++++++----------------------- styles/build.less | 4 ++++ 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 02148d3a..996617ed 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -3,7 +3,6 @@ var _ = require('lodash'); var View = require('atom-space-pen-views').View; -var $ = require('atom-space-pen-views').$; var cscompatability = require('./cscompatability'); var GoogleAnalytics = require('./google-analytics'); var Convert = require('ansi-to-html'); @@ -20,6 +19,8 @@ module.exports = (function() { this.a2h = new Convert(); this.monocle = false; this.starttime = new Date(); + this.buffer = new Buffer(0); + this.links = []; atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this)); @@ -103,6 +104,8 @@ module.exports = (function() { BuildView.prototype.reset = function() { clearTimeout(this.titleTimer); + this.buffer = new Buffer(0); + this.links = []; this.titleTimer = 0; this.title.removeClass('success error warning'); this.output.empty(); @@ -182,22 +185,35 @@ module.exports = (function() { this.titleText.text('Aborted!'); }; + BuildView.prototype._render = function() { + var string = this.a2h.toHtml(_.escape(this.buffer.toString('utf8'))); + _.forEach(this.links, function (link, index) { + string = string.replace(link.text, '' + _.escape(link.text) + ''); + }); + this.output.html(string); + this.output.find('a').on('click', (event) => { + var link = _.findWhere(this.links, { id: event.currentTarget.id }); + link.onClick(); + }); + }; + BuildView.prototype.append = function(data) { - this.output.append(this.a2h.toHtml(_.escape(data))); + this.buffer = Buffer.concat([ this.buffer, Buffer.isBuffer(data) ? data : new Buffer(data) ]); + this._render(); this.output.scrollTop(this.output[0].scrollHeight); }; - BuildView.prototype.replace = function(text, onclick) { - this.output.empty(); - this.output.append(this.a2h.toHtml(text)); - this.output.find('a').on('click', function() { - onclick($(this).attr('id')); + BuildView.prototype.link = function(text, id, onClick) { + this.links.push({ + id: id, + text: text, + onClick: onClick }); - this.output.scrollTop(this.output[0].scrollHeight); + this._render(); }; - BuildView.prototype.scrollTo = function(type, id) { - var position = this.output.find('.' + type + '#' + id).position(); + BuildView.prototype.scrollTo = function(id) { + var position = this.output.find('#' + id).position(); if (position) { this.output.scrollTop(position.top + this.output.scrollTop()); } diff --git a/lib/build.js b/lib/build.js index 050b139b..149c42ad 100644 --- a/lib/build.js +++ b/lib/build.js @@ -123,8 +123,14 @@ module.exports = { atom.notifications.addError('Error matching failed!', { detail: message }); }); - this.errorMatcher.on('scroll', this.buildView.scrollTo.bind(this.buildView)); - this.errorMatcher.on('replace', this.buildView.replace.bind(this.buildView)); + this.errorMatcher.on('matched', (id) => { + this.buildView.scrollTo(id); + }); + + this.errorMatcher.on('match', (text, id) => { + var callback = this.errorMatcher.goto.bind(this.errorMatcher, id); + this.buildView.link(text, id, callback); + }); this.refreshTargets().catch(function(e) {}); }, diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 3dc27163..88bfb920 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -30,10 +30,10 @@ module.exports = (function () { return; } - this._goto(this.currentMatch[0].id); + this.goto(this.currentMatch[0].id); }; - ErrorMatcher.prototype._goto = function (id) { + ErrorMatcher.prototype.goto = function (id) { var match = _.findWhere(this.currentMatch, { id: id }); if (!match) { return this.emit('error', 'Can\'t find match with id ' + id); @@ -65,15 +65,14 @@ module.exports = (function () { initialColumn: col, searchAllPanes: true }); - this.emit('scroll', match.type, match.id); + this.emit('matched', match.id); }.bind(this)); }; ErrorMatcher.prototype._parse = function () { this.currentMatch = []; var matchFunction = function (match, i) { - match.type = 'error'; - match.id = 'error-' + regexIndex + '-' + i; + match.id = 'error-match-' + regexIndex + '-' + i; this.push(match); }; for (var regexIndex in this.regex) { @@ -86,23 +85,9 @@ module.exports = (function () { this.firstMatchId = (this.currentMatch.length > 0) ? this.currentMatch[0].id : null; - var output = ''; - var lastEnd = 0; - for (var matchIndex in this.currentMatch) { - var match = this.currentMatch[matchIndex]; - - if (match.index < lastEnd) { - // overlapping matches, only highlight first - continue; - } - - output += _.escape(this.output.substr(lastEnd, match.index - lastEnd)); - output += util.format('%s', match.type, match.id, _.escape(match[0])); - lastEnd = match.index + match[0].length; - } - output += _.escape(this.output.substr(lastEnd)); - - this.emit('replace', output, this._goto.bind(this)); + _.forEach(this.currentMatch, (match, index) => { + this.emit('match', match[0], match.id); + }); }; ErrorMatcher.prototype.set = function (regex, cwd, output) { @@ -137,7 +122,7 @@ module.exports = (function () { GoogleAnalytics.sendEvent('errorMatch', 'first'); if (this.firstMatchId) { - this._goto(this.firstMatchId); + this.goto(this.firstMatchId); } }; diff --git a/styles/build.less b/styles/build.less index c7894a8b..9011589c 100644 --- a/styles/build.less +++ b/styles/build.less @@ -39,6 +39,10 @@ list-style: none; font-family: monospace; } + + a { + text-decoration: underline; + } } .btn-container { From 4bc49520fe4ece06f7bac968fe1448fcee0b1fd3 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 23 Aug 2015 20:31:00 +0200 Subject: [PATCH 161/495] JSCS: Allow esnext (es6) code --- .jscsrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.jscsrc b/.jscsrc index fa65bfcd..ac6797aa 100644 --- a/.jscsrc +++ b/.jscsrc @@ -29,5 +29,6 @@ "excludeFiles": [ "node_modules/**", "spec/fixture/node_modules/**" - ] + ], + "esnext": true } From 59393d8eec0657fcf52890636af898478db07050 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 20:00:33 +0200 Subject: [PATCH 162/495] Build View: Replace all occurances, and escaped. --- lib/build-view.js | 10 +++++----- package.json | 2 +- spec/build-view-spec.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 996617ed..2b43c367 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -3,9 +3,9 @@ var _ = require('lodash'); var View = require('atom-space-pen-views').View; +var ansi_up = require('ansi_up'); var cscompatability = require('./cscompatability'); var GoogleAnalytics = require('./google-analytics'); -var Convert = require('ansi-to-html'); module.exports = (function() { function BuildView() { @@ -16,7 +16,6 @@ module.exports = (function() { this.n = this.n || 0; (++this.n === 3) && this.push(this.shift()) && (this.n = 0); }; - this.a2h = new Convert(); this.monocle = false; this.starttime = new Date(); this.buffer = new Buffer(0); @@ -186,11 +185,12 @@ module.exports = (function() { }; BuildView.prototype._render = function() { - var string = this.a2h.toHtml(_.escape(this.buffer.toString('utf8'))); + var string = _.escape(this.buffer.toString('utf8')); _.forEach(this.links, function (link, index) { - string = string.replace(link.text, '' + _.escape(link.text) + ''); + var replaceRegex = new RegExp(_.escape(link.text), 'g'); + string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); }); - this.output.html(string); + this.output.html(ansi_up.ansi_to_html(string)); this.output.find('a').on('click', (event) => { var link = _.findWhere(this.links, { id: event.currentTarget.id }); link.onClick(); diff --git a/package.json b/package.json index dfc4e497..5de7cfe1 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "atom": ">=0.50.0" }, "dependencies": { - "ansi-to-html": "^0.3.0", + "ansi_up": "^1.3.0", "atom-space-pen-views": "^2.0.3", "fs-extra": "^0.23.0", "getmac": "^1.0.7", diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 05150b5e..4057761e 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -57,7 +57,7 @@ describe('Visible', function() { }); runs(function () { - expect(workspaceElement.querySelector('.build .output > span').style.color.match(/\d+/g)).toEqual([ '170', '0', '0' ]); + expect(workspaceElement.querySelector('.build .output > span').style.color.match(/\d+/g)).toEqual([ '187', '0', '0' ]); }); }); From c1200457e502948579483dc08e60f27fca6a3241 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 20:02:17 +0200 Subject: [PATCH 163/495] Prepare 0.45.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dfc4e497..0c6ec05e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.44.0", + "version": "0.45.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 879b9ebd6e7b621b2a7e6cef2cd716ce57974cc4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 5 Sep 2015 22:51:57 +0200 Subject: [PATCH 164/495] Correctly escape regular expression --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 2b43c367..3492d2ec 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -187,7 +187,7 @@ module.exports = (function() { BuildView.prototype._render = function() { var string = _.escape(this.buffer.toString('utf8')); _.forEach(this.links, function (link, index) { - var replaceRegex = new RegExp(_.escape(link.text), 'g'); + var replaceRegex = new RegExp(_.escapeRegExp(link.text), 'g'); string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); }); this.output.html(ansi_up.ansi_to_html(string)); From 69e3d1c84a6ef1c3b02776148fbc58bc6d0a3272 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 5 Sep 2015 22:52:15 +0200 Subject: [PATCH 165/495] Don't replace links multiple times If replaced text occurs several times in the output, only set a link for the first one. --- lib/build-view.js | 5 +++++ spec/build-view-spec.js | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/build-view.js b/lib/build-view.js index 3492d2ec..f743f3e4 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -204,6 +204,11 @@ module.exports = (function() { }; BuildView.prototype.link = function(text, id, onClick) { + if (_.findWhere(this.links, { text: text })) { + /* This text already has a link to it. Ignore it. */ + return; + } + this.links.push({ id: id, text: text, diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 4057761e..4b1bc8fa 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -135,4 +135,29 @@ describe('Visible', function() { }); }); }); + + describe('when links are added', function () { + it('should only add one link per text, even if multiple is requested', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo match1 match1 match1 && exit 1', + errorMatch: 'match1' + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + var output = workspaceElement.querySelector('.build .output'); + expect(output.children.length).toEqual(6); + for (var i = 0; i < output.children.length; i++) { + expect(output.children[i].id).toEqual('error-match-0-0'); + } + }); + }); + }); }); From 4c8305f3d02127db266e437f6d35a9aea787b362 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 5 Sep 2015 22:53:14 +0200 Subject: [PATCH 166/495] Error Matcher specs: re-arrange --- spec/build-error-match-spec.js | 50 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index bd4e44d8..48362318 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -45,6 +45,32 @@ describe('Error Match', function() { fs.removeSync(directory); }); + describe('when error matcher is configured incorrectly', function () { + it('should show an error if regex is invalid', function () { + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'return 1', + errorMatch: '(invalidRegex' + })); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + expect(atom.notifications.getNotifications().length).toEqual(1); + + var notification = atom.notifications.getNotifications()[0]; + expect(notification.getType()).toEqual('error'); + expect(notification.getMessage()).toEqual('Error matching failed!'); + expect(notification.options.detail).toMatch(/Unterminated group/); + }); + }); + }); + describe('when output is captured to show editor on error', function () { it('should place the line and column on error in correct file', function () { expect(workspaceElement.querySelector('.build')).not.toExist(); @@ -301,30 +327,6 @@ describe('Error Match', function() { }); }); - it('should show an error if regex is invalid', function () { - - fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'return 1', - errorMatch: '(invalidRegex' - })); - - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - expect(atom.notifications.getNotifications().length).toEqual(1); - - var notification = atom.notifications.getNotifications()[0]; - expect(notification.getType()).toEqual('error'); - expect(notification.getMessage()).toEqual('Error matching failed!'); - expect(notification.options.detail).toMatch(/Unterminated group/); - }); - }); - it('should scroll the build panel to the text of the error', function () { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); From b701f34642f23abb01f158dce5124930ba0c27ac Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 9 Sep 2015 19:50:17 +0200 Subject: [PATCH 167/495] Keymap specificity to not collide On Linux, editor:move-to-previous-subword-boundary is bound to `ctrl-alt-b`. Add specificity to the build keymap to win. Fixes #168 --- keymaps/build.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keymaps/build.json b/keymaps/build.json index 46e1fdeb..6098cac1 100644 --- a/keymaps/build.json +++ b/keymaps/build.json @@ -1,12 +1,12 @@ { - ".platform-darwin atom-workspace": { + ".platform-darwin atom-workspace, .platform-darwin atom-text-editor": { "cmd-alt-b": "build:trigger", "cmd-alt-v": "build:toggle-panel", "cmd-alt-g": "build:error-match", "cmd-alt-h": "build:error-match-first", "cmd-alt-t": "build:select-active-target" }, - ".platform-linux atom-workspace, .platform-win32 atom-workspace": { + ".platform-linux atom-workspace, .platform-linux atom-text-editor, .platform-win32 atom-workspace, .platform-win32 atom-text-editor": { "ctrl-alt-b": "build:trigger", "ctrl-alt-v": "build:toggle-panel", "ctrl-alt-g": "build:error-match", From c01d9da1477882cbddb132f58dc544afa5a34e24 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 9 Sep 2015 21:34:06 +0200 Subject: [PATCH 168/495] Prepare 0.46.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0c6ec05e..792cf054 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.45.0", + "version": "0.46.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From a692b72e03fb6cf14998af9b332c0bf4cd8378ea Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 10 Sep 2015 20:29:14 +0200 Subject: [PATCH 169/495] ErrorMatcher: Defensive array loops Avoid enumerating potential extended properties on the array prototype. --- lib/error-matcher.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 3dc27163..39f5d0d0 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -71,14 +71,15 @@ module.exports = (function () { ErrorMatcher.prototype._parse = function () { this.currentMatch = []; - var matchFunction = function (match, i) { + var self = this; + var matchFunction = function (match, i, string, regex) { match.type = 'error'; - match.id = 'error-' + regexIndex + '-' + i; + match.id = 'error-' + self.regex.indexOf(regex) + '-' + i; this.push(match); }; - for (var regexIndex in this.regex) { - XRegExp.forEach(this.output, this.regex[regexIndex], matchFunction, this.currentMatch); - } + this.regex.forEach((regex) => { + XRegExp.forEach(this.output, regex, matchFunction, this.currentMatch); + }); this.currentMatch.sort(function(a, b) { return a.index - b.index; @@ -88,9 +89,7 @@ module.exports = (function () { var output = ''; var lastEnd = 0; - for (var matchIndex in this.currentMatch) { - var match = this.currentMatch[matchIndex]; - + for (let match of this.currentMatch) { if (match.index < lastEnd) { // overlapping matches, only highlight first continue; From e436c78c95d9de1feed27d84096f13550e765a37 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 10 Sep 2015 20:35:38 +0200 Subject: [PATCH 170/495] JSCS: Allow ES6 (esnext) --- .jscsrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.jscsrc b/.jscsrc index fa65bfcd..ac6797aa 100644 --- a/.jscsrc +++ b/.jscsrc @@ -29,5 +29,6 @@ "excludeFiles": [ "node_modules/**", "spec/fixture/node_modules/**" - ] + ], + "esnext": true } From 019260af67fef1b6b9bf2c3010ae9ee0a9e84d31 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 15 Sep 2015 21:16:42 +0200 Subject: [PATCH 171/495] BuildView: build panel orientation setting Allow to attach the build panel to left, right, top or bottom. This allows people with very wide screens to have them to the right, or to the left. Top might be preferrable by some, so add that too. Solves #171 Solves #88 --- lib/build-view.js | 83 +++++++++++++++++++++++++--------- lib/build.js | 8 ++++ spec/build-error-match-spec.js | 1 - styles/build.less | 3 +- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index f743f3e4..567fab0f 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -3,6 +3,7 @@ var _ = require('lodash'); var View = require('atom-space-pen-views').View; +var $ = require('atom-space-pen-views').$; var ansi_up = require('ansi_up'); var cscompatability = require('./cscompatability'); var GoogleAnalytics = require('./google-analytics'); @@ -21,9 +22,12 @@ module.exports = (function() { this.buffer = new Buffer(0); this.links = []; + this._setMonocleIcon(); + atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); - atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this)); - atom.config.observe('build.minimizedHeight', this.heightFromConfig.bind(this)); + atom.config.observe('build.panelOrientation', this.orientationFromConfig.bind(this)); + atom.config.observe('build.monocleHeight', this.sizeFromConfig.bind(this)); + atom.config.observe('build.minimizedHeight', this.sizeFromConfig.bind(this)); atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this)); } @@ -62,9 +66,15 @@ module.exports = (function() { if (this.panel) { this.panel.destroy(); } - this.panel = atom.workspace.addBottomPanel({ item: this }); - this.height = this.output.offset().top + this.output.height(); - this.heightFromConfig(); + let addfn = { + Top: atom.workspace.addTopPanel, + Bottom: atom.workspace.addBottomPanel, + Left: atom.workspace.addLeftPanel, + Right: atom.workspace.addRightPanel + }; + let orientation = atom.config.get('build.panelOrientation') || 'Bottom'; + this.panel = addfn[orientation].call(atom.workspace, { item: this }); + this.sizeFromConfig(); }; BuildView.prototype.detach = function(force) { @@ -82,12 +92,8 @@ module.exports = (function() { return !!this.panel; }; - BuildView.prototype.heightFromConfig = function() { - if (this.monocle) { - this.setHeightPercent(atom.config.get('build.monocleHeight')); - } else { - this.setHeightPercent(atom.config.get('build.minimizedHeight')); - } + BuildView.prototype.sizeFromConfig = function() { + this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight')); }; BuildView.prototype.visibleFromConfig = function(val) { @@ -101,6 +107,15 @@ module.exports = (function() { } }; + BuildView.prototype.orientationFromConfig = function (val) { + let isVisible = this.isVisible(); + this.detach(true); + if (isVisible) { + this.attach(); + this._setMonocleIcon(); + } + }; + BuildView.prototype.reset = function() { clearTimeout(this.titleTimer); this.buffer = new Buffer(0); @@ -137,21 +152,47 @@ module.exports = (function() { atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:trigger'); }; - BuildView.prototype.setHeightPercent = function(percent) { - var newHeight = percent * this.height; - this.output.css('height', newHeight + 'px'); + BuildView.prototype.setSizePercent = function(percent) { + let size = 0, cssKey = 'height'; + switch (atom.config.get('build.panelOrientation')) { + case 'Top': + case 'Bottom': + size = $('atom-workspace-axis.vertical').height(); + cssKey = 'height'; + break; + + case 'Left': + case 'Right': + size = $('atom-workspace-axis.vertical').width(); + if ($('.build').length) { + size += $('.build').get(0).clientWidth; + } + cssKey = 'width'; + break; + } + this.output.css(cssKey, percent * size + 'px'); + }; + + BuildView.prototype._setMonocleIcon = function () { + let iconName = () => { + switch (atom.config.get('build.panelOrientation')) { + case 'Top': return this.monocle ? 'icon-chevron-up' : 'icon-chevron-down'; + case 'Bottom': return this.monocle ? 'icon-chevron-down' : 'icon-chevron-up'; + case 'Right': return this.monocle ? 'icon-chevron-right' : 'icon-chevron-left'; + case 'Left': return this.monocle ? 'icon-chevron-left' : 'icon-chevron-right'; + } + }; + + this.monocleButton + .removeClass('icon-chevron-down icon-chevron-up icon-chevron-left icon-chevron-right') + .addClass(iconName()); }; BuildView.prototype.toggleMonocle = function(event, element) { GoogleAnalytics.sendEvent('view', 'monocle toggled'); - if (!this.monocle) { - this.setHeightPercent(atom.config.get('build.monocleHeight')); - this.monocleButton.removeClass('icon-chevron-up').addClass('icon-chevron-down'); - } else { - this.setHeightPercent(atom.config.get('build.minimizedHeight')); - this.monocleButton.removeClass('icon-chevron-down').addClass('icon-chevron-up'); - } this.monocle = !this.monocle; + this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight')); + this._setMonocleIcon(); }; BuildView.prototype.buildStarted = function() { diff --git a/lib/build.js b/lib/build.js index 149c42ad..69c59bb5 100644 --- a/lib/build.js +++ b/lib/build.js @@ -80,6 +80,14 @@ module.exports = { minimum: 0.1, maximum: 0.9, order: 7 + }, + panelOrientation: { + title: 'Panel Orientation', + description: 'Where to attach the build panel', + type: 'string', + default: 'Bottom', + enum: [ 'Bottom', 'Top', 'Left', 'Right' ], + order: 8 } }, diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 48362318..fb30c433 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,4 +1,3 @@ -'use babel'; 'use strict'; var fs = require('fs-extra'); diff --git a/styles/build.less b/styles/build.less index 9011589c..729043c4 100644 --- a/styles/build.less +++ b/styles/build.less @@ -30,7 +30,8 @@ } .output { - transition: height 0.5s ease-in-out; + transition: 0.5s ease-in-out; + transition-property: width, height; padding: 10px 0 0 10px; min-height: 100px; overflow-y: auto; From c3c4eea085c1f513b3f3b071351a1b895da75fa2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 16 Sep 2015 19:21:16 +0200 Subject: [PATCH 172/495] Build View: Reset width/height When changing the orientation, the width and height needs to be reset to the default value. --- lib/build-view.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/build-view.js b/lib/build-view.js index 567fab0f..0a54e88a 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -170,6 +170,8 @@ module.exports = (function() { cssKey = 'width'; break; } + this.output.css('width', 'auto'); + this.output.css('height', 'auto'); this.output.css(cssKey, percent * size + 'px'); }; From 86d067a45e3f1affed888846da489b01abea6ee0 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 16 Sep 2015 19:44:02 +0200 Subject: [PATCH 173/495] BuildView: panel orientation specs --- spec/build-view-spec.js | 86 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 4b1bc8fa..004d66e8 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -160,4 +160,90 @@ describe('Visible', function() { }); }); }); + + describe('when panel orientation is altered', function () { + it('should show the panel at the bottom spot', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + atom.config.set('build.panelOrientation', 'Bottom'); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo this will fail && exit 1', + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + var bottomPanels = atom.workspace.getBottomPanels(); + expect(bottomPanels.length).toEqual(1); + expect(bottomPanels[0].item.constructor.name).toEqual('BuildView'); + }); + }); + + it('should show the panel at the bottom spot', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + atom.config.set('build.panelOrientation', 'Left'); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo this will fail && exit 1', + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + var panels = atom.workspace.getLeftPanels(); + expect(panels.length).toEqual(1); + expect(panels[0].item.constructor.name).toEqual('BuildView'); + }); + }); + + it('should show the panel at the bottom spot', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + atom.config.set('build.panelOrientation', 'Top'); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo this will fail && exit 1', + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + var panels = atom.workspace.getTopPanels(); + expect(panels.length).toEqual(1); + expect(panels[0].item.constructor.name).toEqual('BuildView'); + }); + }); + + it('should show the panel at the bottom spot', function () { + expect(workspaceElement.querySelector('.build')).not.toExist(); + atom.config.set('build.panelOrientation', 'Right'); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo this will fail && exit 1', + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + var panels = atom.workspace.getRightPanels(); + expect(panels.length).toEqual(1); + expect(panels[0].item.constructor.name).toEqual('BuildView'); + }); + }); + }); }); From 0240d811214c602fc92a8895ba5f93b6b31ebb93 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 16 Sep 2015 19:48:31 +0200 Subject: [PATCH 174/495] Specs: Correct name of BuildView specs --- spec/build-view-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 004d66e8..d78d85b8 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -5,7 +5,7 @@ var fs = require('fs-extra'); var temp = require('temp'); var specHelpers = require('./spec-helpers'); -describe('Visible', function() { +describe('BuildView', function() { var directory = null; var workspaceElement = null; From 1a4c92eaaa31d7a54937c7ab17e61dd173ca4c36 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 21 Sep 2015 00:54:16 +0200 Subject: [PATCH 175/495] Fix example target JSON The JSON wasn't valid in the example target due to a missing comma. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f99efa1a..aaac262a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ exactly what to execute. Create a file named `.atom-build.json` in your project "errorMatch": [ "^regexp1$", "^regexp2$" - ] + ], "keymap": "", "targets": { "": { From ede1473f9a1f5468930f6845fe6af6da69f4c58b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 22 Sep 2015 19:45:06 +0200 Subject: [PATCH 176/495] BuildView: Force status to bottom The status bar of the build panel should stick to the bottom, no matter where the build panel is placed. --- lib/build-view.js | 2 +- styles/build.less | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 0a54e88a..cf73b10d 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -45,7 +45,7 @@ module.exports = (function() { BuildView.div({ class: 'output panel-body', outlet: 'output' }); - BuildView.div(function() { + BuildView.div({ class: 'status' }, function() { BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, function () { BuildView.span({ class: 'build-timer', outlet: 'buildTimer' }, '0.0 s'); BuildView.span({ class: 'title-text', outlet: 'titleText' }, 'Ready'); diff --git a/styles/build.less b/styles/build.less index 729043c4..92d29b73 100644 --- a/styles/build.less +++ b/styles/build.less @@ -1,6 +1,9 @@ @import "ui-variables"; .build { + + height: 100%; + .title { transition: background-color 0.2s ease-in; } @@ -41,6 +44,12 @@ font-family: monospace; } + .status { + position: absolute; + bottom: 0; + width: 100%; + } + a { text-decoration: underline; } From d44eb1a89bb26fb12bc31b98317b6eec2761f96d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 22 Sep 2015 21:10:39 +0200 Subject: [PATCH 177/495] BuildView: Allow left/right panel to be scrolled --- lib/build-view.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index cf73b10d..d1c7af18 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -170,8 +170,8 @@ module.exports = (function() { cssKey = 'width'; break; } - this.output.css('width', 'auto'); - this.output.css('height', 'auto'); + this.output.css('width', '100%'); + this.output.css('height', '100%'); this.output.css(cssKey, percent * size + 'px'); }; From 75ca7181e42a9602a5e309a5e4ec3c7f7a95a184 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 18:46:04 +0200 Subject: [PATCH 178/495] BuildView: Pad to show bottom lines --- lib/build-view.js | 2 +- styles/build.less | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index d1c7af18..69382a8c 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -170,7 +170,7 @@ module.exports = (function() { cssKey = 'width'; break; } - this.output.css('width', '100%'); + this.output.css('width', 'auto'); this.output.css('height', '100%'); this.output.css(cssKey, percent * size + 'px'); }; diff --git a/styles/build.less b/styles/build.less index 92d29b73..7b267720 100644 --- a/styles/build.less +++ b/styles/build.less @@ -1,4 +1,5 @@ @import "ui-variables"; +@status-panel-height: 3em; .build { @@ -35,19 +36,23 @@ .output { transition: 0.5s ease-in-out; transition-property: width, height; - padding: 10px 0 0 10px; + padding: 10px 0 @status-panel-height 10px; min-height: 100px; - overflow-y: auto; + overflow: auto; word-wrap: break-word; white-space: pre-wrap; - list-style: none; font-family: monospace; } .status { position: absolute; bottom: 0; + height: @status-panel-height; width: 100%; + + h1 { + height: 100%; + } } a { From 2c6682b5edeb4f3e8755f147db18e7fb0bf5ef91 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 19:21:35 +0200 Subject: [PATCH 179/495] Added Warning about bundled tools removal Bundled tools will be removed in v0.48.0. As a preparation, in v0.47.0 a warning will be included which urges the user to install the stand-alone package. The warning will only be shown once, and only if the tool is being used. --- lib/tools/Cargo.js | 10 ++++++++++ lib/tools/Elixir.js | 10 ++++++++++ lib/tools/Grunt.js | 10 ++++++++++ lib/tools/gulp.js | 10 ++++++++++ lib/tools/make.js | 10 ++++++++++ lib/tools/npm_apm.js | 10 ++++++++++ 6 files changed, 60 insertions(+) diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js index 4c936c64..a5ecf7d4 100644 --- a/lib/tools/Cargo.js +++ b/lib/tools/Cargo.js @@ -10,6 +10,16 @@ module.exports.isEligable = function (path) { }; module.exports.settings = function (path) { + if (!atom.config.get('deprecated.tool.cargo')) { + atom.notifications.addWarning('Bundled `Cargo` build will be removed', { + dismissable: true, + detail: + 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + + 'You can install `build-cargo` (apm install build-cargo) at this time and you will be well prepared for the next release!' + }); + atom.config.set('deprecated.tool.cargo', true); + } + return [ { name: 'Cargo: build', exec: 'cargo', diff --git a/lib/tools/Elixir.js b/lib/tools/Elixir.js index 570f867f..536db6e3 100644 --- a/lib/tools/Elixir.js +++ b/lib/tools/Elixir.js @@ -10,6 +10,16 @@ module.exports.isEligable = function (path) { }; module.exports.settings = function (path) { + if (!atom.config.get('deprecated.tool.elixir')) { + atom.notifications.addWarning('Bundled `Elixir` build will be removed', { + dismissable: true, + detail: + 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + + 'You can install `build-elixir` (apm install build-elixir) at this time and you will be well prepared for the next release!' + }); + atom.config.set('deprecated.tool.elixir', true); + } + return [ { name: 'Elixir: default', exec: 'mix', diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js index 5412774c..43797c98 100644 --- a/lib/tools/Grunt.js +++ b/lib/tools/Grunt.js @@ -16,6 +16,16 @@ module.exports.isEligable = function (cwd) { }; module.exports.settings = function (cwd) { + if (!atom.config.get('deprecated.tool.grunt')) { + atom.notifications.addWarning('Bundled `Grunt` build will be removed', { + dismissable: true, + detail: + 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + + 'You can install `build-grunt` (apm install build-grunt) at this time and you will be well prepared for the next release!' + }); + atom.config.set('deprecated.tool.grunt', true); + } + var createConfig = function (name, args) { var executable = /^win/.test(process.platform) ? 'grunt.cmd' : 'grunt'; var localPath = path.join(cwd, 'node_modules', '.bin', executable); diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js index e18b251c..03ff79eb 100644 --- a/lib/tools/gulp.js +++ b/lib/tools/gulp.js @@ -17,6 +17,16 @@ module.exports.isEligable = function (cwd) { }; module.exports.settings = function (cwd) { + if (!atom.config.get('deprecated.tool.gulp')) { + atom.notifications.addWarning('Bundled `gulp` build will be removed', { + dismissable: true, + detail: + 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + + 'You can install `build-gulp` (apm install build-gulp) at this time and you will be well prepared for the next release!' + }); + atom.config.set('deprecated.tool.gulp', true); + } + var createConfig = function (name, args) { var executable = /^win/.test(process.platform) ? 'gulp.cmd' : 'gulp'; var localPath = path.join(cwd, 'node_modules', '.bin', executable); diff --git a/lib/tools/make.js b/lib/tools/make.js index 848c7e8b..9e8521bc 100644 --- a/lib/tools/make.js +++ b/lib/tools/make.js @@ -11,6 +11,16 @@ module.exports.isEligable = function (cwd) { }; module.exports.settings = function (cwd) { + if (!atom.config.get('deprecated.tool.make')) { + atom.notifications.addWarning('Bundled `make` build will be removed', { + dismissable: true, + detail: + 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + + 'You can install `build-make` (apm install build-make) at this time and you will be well prepared for the next release!' + }); + atom.config.set('deprecated.tool.make', true); + } + return [ { name: 'GNU Make: default', exec: 'make', diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js index 9216783a..71ec9ad9 100644 --- a/lib/tools/npm_apm.js +++ b/lib/tools/npm_apm.js @@ -23,6 +23,16 @@ module.exports.isEligable = function (cwd) { }; module.exports.settings = function (cwd) { + if (!atom.config.get('deprecated.tool.npmapm')) { + atom.notifications.addWarning('Bundled `npm` and `apm` build will be removed', { + dismissable: true, + detail: + 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + + 'You can install `build-npm-apm` (apm install build-npm-apm) at this time and you will be well prepared for the next release!' + }); + atom.config.set('deprecated.tool.npmapm', true); + } + var realPackage = fs.realpathSync(path.join(cwd, 'package.json')); var pkg = require(realPackage); From 506555a6fc45bbb33b328f080750410d2bb7e2c4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 19:26:02 +0200 Subject: [PATCH 180/495] ErrorMatch Spec: Scrolling slightly off Scrolling changed a little due to CSS. Should probably not check exact pixel value for this... --- spec/build-error-match-spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index fb30c433..5a208db9 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -348,7 +348,7 @@ describe('Error Match', function() { waits(100); runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(135); + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(168); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); @@ -381,7 +381,7 @@ describe('Error Match', function() { waits(100); runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(135); + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(168); atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); From 548b708fffe84ab6b8ae4124ec44ece3dfbf3a16 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 24 Sep 2015 19:41:46 +0200 Subject: [PATCH 181/495] Prepare 0.47.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9b5f2f6a..e5d6e88f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.46.0", + "version": "0.47.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 62075f1bb224b27c0a0eed06927248247ba2d7b4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 23 Aug 2015 20:49:28 +0200 Subject: [PATCH 182/495] Migrated gulp to noseglid/atom-build-gulp --- lib/tools/gulp-parser-task.js | 32 ---------------- lib/tools/gulp.js | 72 ----------------------------------- lib/tools/index.js | 1 - 3 files changed, 105 deletions(-) delete mode 100644 lib/tools/gulp-parser-task.js delete mode 100644 lib/tools/gulp.js diff --git a/lib/tools/gulp-parser-task.js b/lib/tools/gulp-parser-task.js deleted file mode 100644 index f3cb1021..00000000 --- a/lib/tools/gulp-parser-task.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -/** - * This has to be done in a separate task since gulp depends - * on stuff that does unsafe evals. We don't want, and are not - * allowed to do this in the context of the Atom application. - */ - -try { - var gulp = require('gulp'); -} catch (e) {} - -module.exports = function (path) { - try { - if (!gulp) { - throw new Error('Gulp is not installed.'); - } - - process.chdir(path); - - /* jshint -W020 */ - /* When spawning this, we are not a browser anymore. Disable these */ - navigator = undefined; - window = undefined; - /* jshint +W020 */ - - require(path + '/gulpfile.js'); - return { tasks: Object.keys(gulp.tasks) }; - } catch (e) { - return { error: { message: e.message } }; - } -}; diff --git a/lib/tools/gulp.js b/lib/tools/gulp.js deleted file mode 100644 index 03ff79eb..00000000 --- a/lib/tools/gulp.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; - -var fs = require('fs'); -var path = require('path'); -var util = require('util'); -var _ = require('lodash'); -var Task = require('atom').Task; - -var originalNodePath = process.env.NODE_PATH; - -module.exports.niceName = 'gulp'; - -module.exports.isEligable = function (cwd) { - return fs.existsSync(path.join(cwd, 'gulpfile.js')) || - fs.existsSync(path.join(cwd, 'gulpfile.coffee')) || - fs.existsSync(path.join(cwd, 'gulpfile.babel.js')); -}; - -module.exports.settings = function (cwd) { - if (!atom.config.get('deprecated.tool.gulp')) { - atom.notifications.addWarning('Bundled `gulp` build will be removed', { - dismissable: true, - detail: - 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + - 'You can install `build-gulp` (apm install build-gulp) at this time and you will be well prepared for the next release!' - }); - atom.config.set('deprecated.tool.gulp', true); - } - - var createConfig = function (name, args) { - var executable = /^win/.test(process.platform) ? 'gulp.cmd' : 'gulp'; - var localPath = path.join(cwd, 'node_modules', '.bin', executable); - var exec = fs.existsSync(localPath) ? localPath : executable; - return { - name: name, - exec: exec, - sh: false, - args: args - }; - }; - - return new Promise(function(resolve, reject) { - /* This is set so that the spawned Task gets its own instance of gulp */ - process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); - - Task.once(require.resolve('./gulp-parser-task.js'), cwd, function (result) { - if (result.error) { - return resolve([ createConfig('Gulp: default', [ 'default' ]) ]); - } - - var config = []; - /* Make sure 'default' is the first as this will be the prioritized target */ - result.tasks.sort(function (t1, t2) { - if ('default' === t1) { - return -1; - } - if ('default' === t2) { - return 1; - } - return t1.localeCompare(t2); - }); - _.forEach(result.tasks || [], function (task) { - config.push(createConfig('Gulp: ' + task, [ task ])); - }); - - return resolve(config); - }); - }).catch(function (err) { - process.env.NODE_PATH = originalNodePath; - throw err; - }); -}; diff --git a/lib/tools/index.js b/lib/tools/index.js index 2d498220..473fc7b7 100644 --- a/lib/tools/index.js +++ b/lib/tools/index.js @@ -13,7 +13,6 @@ module.exports = [ /* semi-generic (may trigger other build scripts) */ require('./npm_apm'), require('./Grunt'), - require('./gulp'), require('./make'), /* specific (builds only one thing) */ From 80cd371c22c77e0b651af5a340e6bed69a9900bb Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 23 Aug 2015 20:49:44 +0200 Subject: [PATCH 183/495] Migrated make to noseglid/atom-build-make --- lib/tools/index.js | 1 - lib/tools/make.js | 29 ----------------------------- 2 files changed, 30 deletions(-) delete mode 100644 lib/tools/make.js diff --git a/lib/tools/index.js b/lib/tools/index.js index 473fc7b7..ff69f69d 100644 --- a/lib/tools/index.js +++ b/lib/tools/index.js @@ -13,7 +13,6 @@ module.exports = [ /* semi-generic (may trigger other build scripts) */ require('./npm_apm'), require('./Grunt'), - require('./make'), /* specific (builds only one thing) */ require('./Elixir'), diff --git a/lib/tools/make.js b/lib/tools/make.js deleted file mode 100644 index 9e8521bc..00000000 --- a/lib/tools/make.js +++ /dev/null @@ -1,29 +0,0 @@ -'use babel'; -'use strict'; - -var path = require('path'); -var fs = require('fs'); - -module.exports.niceName = 'GNU Make'; - -module.exports.isEligable = function (cwd) { - return fs.existsSync(path.join(cwd, 'Makefile')); -}; - -module.exports.settings = function (cwd) { - if (!atom.config.get('deprecated.tool.make')) { - atom.notifications.addWarning('Bundled `make` build will be removed', { - dismissable: true, - detail: - 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + - 'You can install `build-make` (apm install build-make) at this time and you will be well prepared for the next release!' - }); - atom.config.set('deprecated.tool.make', true); - } - - return [ { - name: 'GNU Make: default', - exec: 'make', - sh: false - } ]; -}; From da160c8c5634ed73c25cb1e59213deccdbb3ba74 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 21:12:16 +0200 Subject: [PATCH 184/495] Specs: Removed all references to 'Makefile' --- spec/build-confirm-spec.js | 62 ++++++--- spec/build-spec.js | 258 ++--------------------------------- spec/build-view-spec.js | 8 +- spec/build-visible-spec.js | 30 +++- spec/fixture/Makefile.bad | 3 - spec/fixture/Makefile.escape | 2 - spec/fixture/Makefile.good | 3 - spec/fixture/Makefile.long | 4 - 8 files changed, 80 insertions(+), 290 deletions(-) delete mode 100644 spec/fixture/Makefile.bad delete mode 100644 spec/fixture/Makefile.escape delete mode 100644 spec/fixture/Makefile.good delete mode 100644 spec/fixture/Makefile.long diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 3cd92de5..5e11da5f 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -6,8 +6,6 @@ var fs = require('fs-extra'); var temp = require('temp'); describe('Confirm', function() { - var goodMakefile = __dirname + '/fixture/Makefile.good'; - var directory = null; var workspaceElement = null; @@ -42,10 +40,12 @@ describe('Confirm', function() { it('should show the save confirmation', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); runs(function() { @@ -66,10 +66,12 @@ describe('Confirm', function() { it('should cancel the confirm window when pressing escape', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); runs(function() { @@ -91,10 +93,12 @@ describe('Confirm', function() { it('should not confirm if a TextEditor edits an unsaved file', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); waitsForPromise(function() { @@ -116,22 +120,26 @@ describe('Confirm', function() { runs(function() { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); it('should save and build when selecting save and build', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('dummy:\n\techo kansas\n'); + editor.setText(JSON.stringify({ + cmd: 'echo kansas' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -159,15 +167,19 @@ describe('Confirm', function() { it('should build but not save when opting so', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('dummy:\n\techo kansas\n'); + editor.setText(JSON.stringify({ + cmd: 'echo kansas' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -195,15 +207,19 @@ describe('Confirm', function() { it('should do nothing when cancelling', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('dummy:\n\techo kansas\n'); + editor.setText(JSON.stringify({ + cmd: 'echo kansas' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -229,15 +245,19 @@ describe('Confirm', function() { it('should only keep at maximum 1 dialog open', function () { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { - return atom.workspace.open('Makefile'); + return atom.workspace.open('.atom-build.json'); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.insertText('hello kansas'); + editor.setText(JSON.stringify({ + cmd: 'echo kansas' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); diff --git a/spec/build-spec.js b/spec/build-spec.js index bcf81243..0e681327 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -7,9 +7,6 @@ var temp = require('temp'); var specHelpers = require('./spec-helpers'); describe('Build', function() { - var goodMakefile = __dirname + '/fixture/Makefile.good'; - var badMakefile = __dirname + '/fixture/Makefile.bad'; - var longMakefile = __dirname + '/fixture/Makefile.long'; var goodGruntfile = __dirname + '/fixture/Gruntfile.js'; var goodGulpfile = __dirname + '/fixture/gulpfile.js'; var goodNodefile = __dirname + '/fixture/package.json.node'; @@ -67,7 +64,9 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo hello world' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { @@ -88,84 +87,6 @@ describe('Build', function() { }); }); - describe('when build is triggered with Makefile', function() { - it('should not show the build window if no buildfile exists', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ - waits(200); - - runs(function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - }); - }); - - it('should show the build window if buildfile exists', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); - }); - }); - - it('should show build failed if build fails', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(badMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); - }); - }); - - it('should cancel build when stopping it, and remove when stopping again', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(longMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - // Let build run for one second before we terminate it - waits(1000); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Building, this will take some time.../); - atom.commands.dispatch(workspaceElement, 'build:stop'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:stop'); - }); - - waitsFor(function() { - return (workspaceElement.querySelector('.build .title .title-text').textContent == 'Aborted!'); - }); - }); - }); - describe('when build is triggered with grunt file', function() { it('should show the build window', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); @@ -448,169 +369,6 @@ describe('Build', function() { }); }); - describe('when build is triggered with gulp file', function() { - it('should show the build window', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - waitsForPromise(function () { - return Promise.resolve() - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGulp(directory)); - }); - - runs(function () { - fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/gulp built/); - }); - }); - - it('should run default target if gulp is not installed', function () { - fs.writeFileSync(directory + 'gulpfile.js', fs.readFileSync(goodGulpfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: gulp/); - }); - }); - }); - - describe('when multiple build options are available', function() { - it('should prioritise .atom-build.json over node', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); - }); - }); - - it('should prioritise grunt over make', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - waitsForPromise(function () { - return Promise.resolve() - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGrunt(directory)); - }); - - runs(function () { - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Running "default" task/); - }); - }); - - it('should prioritise node over grunt', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - waitsForPromise(function () { - return Promise.resolve() - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGrunt(directory)); - }); - - runs(function () { - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: npm/); - }); - }); - - it('should prioritise atom over grunt', function() { - if (process.env.TRAVIS) { - return; - } - expect(workspaceElement.querySelector('.build')).not.toExist(); - - waitsForPromise(function () { - return Promise.resolve() - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGrunt(directory)); - }); - - runs(function () { - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }, 'build to be successful', 10000); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: apm/); - }); - }); - }); - - describe('when package.json exists, but without engines and Makefile is present', function() { - it('(Issue#3) should run Makefile without any npm arguments', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'package.json', fs.readFileSync(badPackageJsonfile)); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); - - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); - }); - }); - }); - describe('when replacements are specified in the atom-build.json file', function() { it('should replace those with their dynamic value', function() { @@ -650,7 +408,9 @@ describe('Build', function() { it('should build when buildOnSave is true', function() { atom.config.set('build.buildOnSave', true); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); waitsForPromise(function() { return atom.workspace.open('dummy'); @@ -668,14 +428,16 @@ describe('Build', function() { runs(function() { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); it('should not build when buildOnSave is false', function() { atom.config.set('build.buildOnSave', false); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(goodMakefile)); + fs.writeFileSync(directory + '.atom-build.json', { + cmd: 'echo "hello, world"' + }); waitsForPromise(function() { return atom.workspace.open('dummy'); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index d78d85b8..957cb3ed 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -100,7 +100,9 @@ describe('BuildView', function() { it('should escape HTML chars so the output is not garbled or missing', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.escape')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo ""' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); waitsFor(function() { @@ -119,7 +121,9 @@ describe('BuildView', function() { it('should include a timer of the build', function () { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.long')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo "Building, this will take some time..." && sleep 30 && echo "Done!"' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); // Let build run for 1.2 second. This should set the timer at "at least" 1.2 diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index 6b5cd8c9..ed5927f2 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -79,10 +79,12 @@ describe('Visible', function() { }); describe('when panel visibility is set to Show on Error', function() { - it('should only show an the build panel if a build fails', function () { + it('should only show the build panel if a build fails', function () { atom.config.set('build.panelVisibility', 'Show on Error'); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.good')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); /* Give it some reasonable time to show itself if there is a bug */ @@ -93,7 +95,15 @@ describe('Visible', function() { }); runs(function () { - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.bad')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo "Very bad..." && exit 2' + })); + }); + + // .atom-build.json is updated asynchronously... give it some time + waits(200); + + runs(function () { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -111,7 +121,9 @@ describe('Visible', function() { it('should not show the build panel if build succeeeds', function () { atom.config.set('build.panelVisibility', 'Hidden'); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.good')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); /* Give it some reasonable time to show itself if there is a bug */ @@ -125,7 +137,9 @@ describe('Visible', function() { it('should not show the build panel if build fails', function () { atom.config.set('build.panelVisibility', 'Hidden'); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.bad')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo "Very bad..." && exit 2' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); /* Give it some reasonable time to show itself if there is a bug */ @@ -139,7 +153,9 @@ describe('Visible', function() { it('should show the build panel if it is toggled', function () { atom.config.set('build.panelVisibility', 'Hidden'); - fs.writeFileSync(directory + 'Makefile', fs.readFileSync(__dirname + '/fixture/Makefile.good')); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + })); atom.commands.dispatch(workspaceElement, 'build:trigger'); waits(200); // Let build finish. Since UI component is not visible yet, there's nothing to poll. @@ -154,7 +170,7 @@ describe('Visible', function() { }); runs(function() { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time\nbut not so, as the time of passing/); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); }); diff --git a/spec/fixture/Makefile.bad b/spec/fixture/Makefile.bad deleted file mode 100644 index 216e7a16..00000000 --- a/spec/fixture/Makefile.bad +++ /dev/null @@ -1,3 +0,0 @@ -all: - @echo "Very bad..." - @exit 2 diff --git a/spec/fixture/Makefile.escape b/spec/fixture/Makefile.escape deleted file mode 100644 index c91bfa67..00000000 --- a/spec/fixture/Makefile.escape +++ /dev/null @@ -1,2 +0,0 @@ -all: - @echo "" diff --git a/spec/fixture/Makefile.good b/spec/fixture/Makefile.good deleted file mode 100644 index ef0a4f11..00000000 --- a/spec/fixture/Makefile.good +++ /dev/null @@ -1,3 +0,0 @@ -all: - @echo "Surprising is the passing of time" - @echo "but not so, as the time of passing" diff --git a/spec/fixture/Makefile.long b/spec/fixture/Makefile.long deleted file mode 100644 index ddcaa9ed..00000000 --- a/spec/fixture/Makefile.long +++ /dev/null @@ -1,4 +0,0 @@ -all: - @echo "Building, this will take some time..." - @sleep 30 - @echo "Done!" From 177cd224da9af0e2539995e87bf1e74378311b82 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 21:12:31 +0200 Subject: [PATCH 185/495] Spec: Removed all references to gulp --- spec/build-spec.js | 1 - spec/build-targets-spec.js | 48 -------------------------------------- spec/fixture/gulpfile.js | 15 ------------ spec/spec-helpers.js | 13 ----------- 4 files changed, 77 deletions(-) delete mode 100644 spec/fixture/gulpfile.js diff --git a/spec/build-spec.js b/spec/build-spec.js index 0e681327..cb53825d 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -8,7 +8,6 @@ var specHelpers = require('./spec-helpers'); describe('Build', function() { var goodGruntfile = __dirname + '/fixture/Gruntfile.js'; - var goodGulpfile = __dirname + '/fixture/gulpfile.js'; var goodNodefile = __dirname + '/fixture/package.json.node'; var goodAtomfile = __dirname + '/fixture/package.json.atom'; var badPackageJsonfile = __dirname + '/fixture/package.json.noengine'; diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 72f1ea52..d9ed4edb 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -88,32 +88,6 @@ describe('Target', function() { }); }); - it('should list those targets in a SelectListView (from gulpfile.js)', function () { - waitsForPromise(function () { - return Promise.resolve() - .then(function () { - return specHelpers.vouch(fs.copy, __dirname + '/fixture/gulpfile.js', directory + '/gulpfile.js'); - }) - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGulp(directory)); - }); - - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:select-active-target'); - }); - - waitsFor(function () { - return workspaceElement.querySelector('.select-list li.build-target'); - }); - - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); - expect(targets).toEqual([ 'Gulp: default', 'Gulp: dev build', 'Gulp: watch' ]); - }); - }); - it('should mark the first target as active', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; @@ -239,28 +213,6 @@ describe('Target', function() { }); describe('when a tool is unable to extract targets', function () { - it('should still list the default target for gulp', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/gulpfile.js'; - return specHelpers.vouch(fs.copy, file, directory + '/gulpfile.js'); - }); - - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:select-active-target'); - }); - - waitsFor(function () { - return workspaceElement.querySelector('.select-list li.build-target'); - }); - - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); - expect(targets).toEqual([ 'Gulp: default' ]); - }); - }); - it('should still list the default target for Grunt', function () { waitsForPromise(function () { var file = __dirname + '/fixture/Gruntfile.js'; diff --git a/spec/fixture/gulpfile.js b/spec/fixture/gulpfile.js deleted file mode 100644 index f57a04b8..00000000 --- a/spec/fixture/gulpfile.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); - -gulp.task('dev build', function () { - console.log('dev build'); -}); - -gulp.task('default', function() { - console.log('gulp built'); -}); - -gulp.task('watch', function () { - console.log('watch'); -}); diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js index 90adbaca..7e62cc36 100644 --- a/spec/spec-helpers.js +++ b/spec/spec-helpers.js @@ -24,19 +24,6 @@ module.exports = { }.bind(this); }, - setupGulp: function (directory) { - var binGulp = path.join(directory, 'node_modules', '.bin', 'gulp'); - var realGulp = path.join(directory, 'node_modules', 'gulp', 'bin', 'gulp.js'); - return function () { - return Promise.all([ - this.vouch(fs.unlink, binGulp), - this.vouch(fs.chmod, realGulp, parseInt('0700', 8)) - ]).then(function () { - return this.vouch(fs.symlink, realGulp, binGulp); - }.bind(this)); - }.bind(this); - }, - _dispatchKeyboardEvent: function (type, element, key, ctrl, alt, shift, meta) { var charCode = key.charCodeAt(0); var unicode = 'U+00' + charCode.toString(16).toUpperCase(); From 8d54cfba7a16dd63682329c84f2481b4b1a0be7d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 23:14:57 +0200 Subject: [PATCH 186/495] Spec: Added tests originally using Makefile These tests where accidentially removed when removing the GNU Make tool. The tests are actually generic to the build package and fits here. They where migrated to use '.atom-build.json' instead. --- spec/build-spec.js | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/spec/build-spec.js b/spec/build-spec.js index cb53825d..d9acd9e7 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -57,6 +57,71 @@ describe('Build', function() { }); }); + describe('when building', function () { + it('should show build failed if build fails', function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo Very bad... && exit 1' + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); + }); + }); + + it('should cancel build when stopping it, and remove when stopping again', function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo "Building, this will take some time..." && sleep 30 && echo "Done!"' + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + // Let build run for one second before we terminate it + waits(1000); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Building, this will take some time.../); + atom.commands.dispatch(workspaceElement, 'build:stop'); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function() { + atom.commands.dispatch(workspaceElement, 'build:stop'); + }); + + waitsFor(function() { + return (workspaceElement.querySelector('.build .title .title-text').textContent == 'Aborted!'); + }); + }); + + it('should not show the build panel if no build file exists', function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ + waits(200); + + runs(function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + }); + }); + }); + describe('when build is triggered twice', function() { it('should not leave multiple panels behind', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); From 8fbc208185620103d9fadddb0c60a2248a8fc516 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 23:49:55 +0200 Subject: [PATCH 187/495] Removed all references to Grunt --- lib/tools/Grunt.js | 71 ---------------------------------- lib/tools/grunt-parser-task.js | 32 --------------- lib/tools/index.js | 1 - spec/build-spec.js | 42 -------------------- spec/build-targets-spec.js | 50 ------------------------ spec/fixture/Gruntfile.js | 16 -------- spec/spec-helpers.js | 22 ----------- 7 files changed, 234 deletions(-) delete mode 100644 lib/tools/Grunt.js delete mode 100644 lib/tools/grunt-parser-task.js delete mode 100644 spec/fixture/Gruntfile.js diff --git a/lib/tools/Grunt.js b/lib/tools/Grunt.js deleted file mode 100644 index 43797c98..00000000 --- a/lib/tools/Grunt.js +++ /dev/null @@ -1,71 +0,0 @@ -'use babel'; -'use strict'; - -var fs = require('fs'); -var path = require('path'); -var util = require('util'); -var _ = require('lodash'); -var Task = require('atom').Task; - -var originalNodePath = process.env.NODE_PATH; - -module.exports.niceName = 'Grunt'; - -module.exports.isEligable = function (cwd) { - return fs.existsSync(path.join(cwd, 'Gruntfile.js')); -}; - -module.exports.settings = function (cwd) { - if (!atom.config.get('deprecated.tool.grunt')) { - atom.notifications.addWarning('Bundled `Grunt` build will be removed', { - dismissable: true, - detail: - 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + - 'You can install `build-grunt` (apm install build-grunt) at this time and you will be well prepared for the next release!' - }); - atom.config.set('deprecated.tool.grunt', true); - } - - var createConfig = function (name, args) { - var executable = /^win/.test(process.platform) ? 'grunt.cmd' : 'grunt'; - var localPath = path.join(cwd, 'node_modules', '.bin', executable); - var exec = fs.existsSync(localPath) ? localPath : executable; - return { - name: name, - exec: exec, - sh: false, - args: args - }; - }; - - return new Promise(function(resolve, reject) { - /* This is set so that the spawned Task gets its own instance of grunt */ - process.env.NODE_PATH = util.format('%s%snode_modules%s%s', cwd, path.sep, path.delimiter, originalNodePath); - - Task.once(require.resolve('./grunt-parser-task.js'), cwd, function (result) { - if (result.error) { - return resolve([ createConfig('Grunt: default', [ 'default' ]) ]); - } - - var config = []; - /* Make sure 'default' is the first as this will be the prioritized target */ - result.tasks.sort(function (t1, t2) { - if ('default' === t1) { - return -1; - } - if ('default' === t2) { - return 1; - } - return t1.localeCompare(t2); - }); - _.forEach(result.tasks || [], function (task) { - config.push(createConfig('Grunt: ' + task, [ task ])); - }); - - return resolve(config); - }); - }).catch(function (err) { - process.env.NODE_PATH = originalNodePath; - throw err; - }); -}; diff --git a/lib/tools/grunt-parser-task.js b/lib/tools/grunt-parser-task.js deleted file mode 100644 index 48d338de..00000000 --- a/lib/tools/grunt-parser-task.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -/** - * This has to be done in a separate task since Grunt depends - * on stuff that does unsafe evals. We don't want, and are not - * allowed to do this in the context of the Atom application. - */ - -try { - var grunt = require('grunt'); -} catch (e) {} - -module.exports = function (path) { - try { - if (!grunt) { - throw new Error('Grunt is not installed.'); - } - - process.chdir(path); - - /* jshint -W020 */ - /* When spawning this, we are not a browser anymore. Disable these */ - navigator = undefined; - window = undefined; - /* jshint +W020 */ - - require(path + '/Gruntfile.js')(grunt); - return { tasks: Object.keys(grunt.task._tasks) }; - } catch (e) { - return { error: { message: e.message } }; - } -}; diff --git a/lib/tools/index.js b/lib/tools/index.js index ff69f69d..9fd9af72 100644 --- a/lib/tools/index.js +++ b/lib/tools/index.js @@ -12,7 +12,6 @@ module.exports = [ /* semi-generic (may trigger other build scripts) */ require('./npm_apm'), - require('./Grunt'), /* specific (builds only one thing) */ require('./Elixir'), diff --git a/spec/build-spec.js b/spec/build-spec.js index d9acd9e7..f5c02f11 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -7,7 +7,6 @@ var temp = require('temp'); var specHelpers = require('./spec-helpers'); describe('Build', function() { - var goodGruntfile = __dirname + '/fixture/Gruntfile.js'; var goodNodefile = __dirname + '/fixture/package.json.node'; var goodAtomfile = __dirname + '/fixture/package.json.atom'; var badPackageJsonfile = __dirname + '/fixture/package.json.noengine'; @@ -151,47 +150,6 @@ describe('Build', function() { }); }); - describe('when build is triggered with grunt file', function() { - it('should show the build window', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - waitsForPromise(function () { - return Promise.resolve() - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGrunt(directory)); - }); - - runs(function () { - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time. But not so, as the time of passing/); - }); - }); - - it('should run default target if grunt is not installed', function () { - fs.writeFileSync(directory + 'Gruntfile.js', fs.readFileSync(goodGruntfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('error'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: grunt/); - }); - }); - }); - describe('when build is triggered with package.json file', function() { it('should show the build window if it is node engine', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index d9ed4edb..d9fc659f 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -62,32 +62,6 @@ describe('Target', function() { }); }); - it('should list those targets in a SelectListView (from Gruntfile.js)', function () { - waitsForPromise(function () { - return Promise.resolve() - .then(function () { - return specHelpers.vouch(fs.copy, __dirname + '/fixture/Gruntfile.js', directory + '/Gruntfile.js'); - }) - .then(specHelpers.setupNodeModules(directory)) - .then(specHelpers.setupGrunt(directory)); - }); - - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:select-active-target'); - }); - - waitsFor(function () { - return workspaceElement.querySelector('.select-list li.build-target'); - }); - - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); - expect(targets).toEqual([ 'Grunt: default', 'Grunt: dev task', 'Grunt: other task', ]); - }); - }); - it('should mark the first target as active', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; @@ -211,28 +185,4 @@ describe('Target', function() { }); }); }); - - describe('when a tool is unable to extract targets', function () { - it('should still list the default target for Grunt', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/Gruntfile.js'; - return specHelpers.vouch(fs.copy, file, directory + '/Gruntfile.js'); - }); - - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:select-active-target'); - }); - - waitsFor(function () { - return workspaceElement.querySelector('.select-list li.build-target'); - }); - - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); - expect(targets).toEqual([ 'Grunt: default' ]); - }); - }); - }); }); diff --git a/spec/fixture/Gruntfile.js b/spec/fixture/Gruntfile.js deleted file mode 100644 index 5522eaf2..00000000 --- a/spec/fixture/Gruntfile.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = function(grunt) { - 'use strict'; - - grunt.initConfig({}); - grunt.registerTask('other task', function () { - console.log('doing heavy machinery stuff'); - }); - - grunt.registerTask('default', function() { - console.log('Surprising is the passing of time. But not so, as the time of passing'); - }); - - grunt.registerTask('dev task', function () { - console.log('doing dev build'); - }); -}; diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js index 7e62cc36..b81dc673 100644 --- a/spec/spec-helpers.js +++ b/spec/spec-helpers.js @@ -1,29 +1,7 @@ 'use babel'; 'use strict'; -var path = require('path'); -var fs = require('fs-extra'); - module.exports = { - setupNodeModules: function (directory) { - return function () { - return this.vouch(fs.copy, path.join(__dirname, 'fixture', 'node_modules'), path.join(directory, 'node_modules')); - }.bind(this); - }, - - setupGrunt: function (directory) { - var binGrunt = path.join(directory, 'node_modules', '.bin', 'grunt'); - var realGrunt = path.join(directory, 'node_modules', 'grunt-cli', 'bin', 'grunt'); - return function () { - return Promise.all([ - this.vouch(fs.unlink, binGrunt), - this.vouch(fs.chmod, realGrunt, parseInt('0700', 8)) - ]).then(function () { - return this.vouch(fs.symlink, realGrunt, binGrunt); - }.bind(this)); - }.bind(this); - }, - _dispatchKeyboardEvent: function (type, element, key, ctrl, alt, shift, meta) { var charCode = key.charCodeAt(0); var unicode = 'U+00' + charCode.toString(16).toUpperCase(); From 0ed031babb7118fc98d6545bf02f46a38f767df3 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 23:51:41 +0200 Subject: [PATCH 188/495] Removed unused fixtured gulp/grunt --- spec/fixture/node_modules/.bin/grunt | 1 - spec/fixture/node_modules/.bin/gulp | 1 - .../fixture/node_modules/grunt-cli/.npmignore | 3 - .../node_modules/grunt-cli/.travis.yml | 4 - spec/fixture/node_modules/grunt-cli/AUTHORS | 4 - .../node_modules/grunt-cli/Gruntfile.js | 49 - .../node_modules/grunt-cli/LICENSE-MIT | 22 - spec/fixture/node_modules/grunt-cli/README.md | 30 - spec/fixture/node_modules/grunt-cli/bin/grunt | 45 - .../node_modules/grunt-cli/completion/bash | 49 - .../node_modules/grunt-cli/completion/zsh | 37 - .../fixture/node_modules/grunt-cli/lib/cli.js | 24 - .../node_modules/grunt-cli/lib/completion.js | 34 - .../node_modules/grunt-cli/lib/info.js | 51 - .../grunt-cli/node_modules/.bin/nopt | 1 - .../node_modules/findup-sync/.jshintrc | 15 - .../node_modules/findup-sync/.npmignore | 0 .../node_modules/findup-sync/.travis.yml | 5 - .../node_modules/findup-sync/Gruntfile.js | 25 - .../node_modules/findup-sync/LICENSE-MIT | 22 - .../node_modules/findup-sync/README.md | 45 - .../findup-sync/lib/findup-sync.js | 46 - .../findup-sync/node_modules/glob/.npmignore | 2 - .../findup-sync/node_modules/glob/.travis.yml | 3 - .../findup-sync/node_modules/glob/LICENSE | 27 - .../findup-sync/node_modules/glob/README.md | 250 - .../node_modules/glob/examples/g.js | 9 - .../node_modules/glob/examples/usr-local.js | 9 - .../findup-sync/node_modules/glob/glob.js | 728 - .../glob/node_modules/inherits/LICENSE | 16 - .../glob/node_modules/inherits/README.md | 42 - .../glob/node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../glob/node_modules/inherits/package.json | 51 - .../glob/node_modules/inherits/test.js | 25 - .../glob/node_modules/minimatch/.npmignore | 1 - .../glob/node_modules/minimatch/LICENSE | 23 - .../glob/node_modules/minimatch/README.md | 218 - .../glob/node_modules/minimatch/minimatch.js | 1061 - .../node_modules/lru-cache/.npmignore | 1 - .../node_modules/lru-cache/CONTRIBUTORS | 14 - .../minimatch/node_modules/lru-cache/LICENSE | 23 - .../node_modules/lru-cache/README.md | 97 - .../node_modules/lru-cache/lib/lru-cache.js | 252 - .../node_modules/lru-cache/package.json | 50 - .../node_modules/lru-cache/test/basic.js | 369 - .../node_modules/lru-cache/test/foreach.js | 52 - .../lru-cache/test/memory-leak.js | 50 - .../minimatch/node_modules/sigmund/LICENSE | 27 - .../minimatch/node_modules/sigmund/README.md | 53 - .../minimatch/node_modules/sigmund/bench.js | 283 - .../node_modules/sigmund/package.json | 58 - .../minimatch/node_modules/sigmund/sigmund.js | 39 - .../node_modules/sigmund/test/basic.js | 24 - .../glob/node_modules/minimatch/package.json | 57 - .../glob/node_modules/minimatch/test/basic.js | 399 - .../minimatch/test/brace-expand.js | 33 - .../node_modules/minimatch/test/caching.js | 14 - .../node_modules/minimatch/test/defaults.js | 274 - .../test/extglob-ending-with-state-char.js | 8 - .../node_modules/glob/package.json | 58 - .../node_modules/glob/test/00-setup.js | 176 - .../node_modules/glob/test/bash-comparison.js | 63 - .../node_modules/glob/test/bash-results.json | 351 - .../node_modules/glob/test/cwd-test.js | 55 - .../node_modules/glob/test/globstar-match.js | 19 - .../node_modules/glob/test/mark.js | 118 - .../glob/test/new-glob-optional-options.js | 10 - .../node_modules/glob/test/nocase-nomagic.js | 113 - .../node_modules/glob/test/pause-resume.js | 73 - .../node_modules/glob/test/readme-issue.js | 36 - .../node_modules/glob/test/root-nomount.js | 39 - .../node_modules/glob/test/root.js | 46 - .../node_modules/glob/test/stat.js | 32 - .../node_modules/glob/test/zz-cleanup.js | 11 - .../node_modules/lodash/LICENSE.txt | 22 - .../findup-sync/node_modules/lodash/README.md | 163 - .../node_modules/lodash/dist/lodash.compat.js | 7157 ------ .../lodash/dist/lodash.compat.min.js | 61 - .../node_modules/lodash/dist/lodash.js | 6785 ------ .../node_modules/lodash/dist/lodash.min.js | 56 - .../lodash/dist/lodash.underscore.js | 4979 ---- .../lodash/dist/lodash.underscore.min.js | 39 - .../findup-sync/node_modules/lodash/lodash.js | 7179 ------ .../node_modules/lodash/package.json | 132 - .../node_modules/findup-sync/package.json | 65 - .../findup-sync/test/findup-sync_test.js | 48 - .../findup-sync/test/fixtures/a.txt | 0 .../findup-sync/test/fixtures/a/b/bar.txt | 0 .../findup-sync/test/fixtures/a/foo.txt | 0 .../findup-sync/test/fixtures/aaa.txt | 0 .../grunt-cli/node_modules/nopt/.gitignore | 0 .../grunt-cli/node_modules/nopt/LICENSE | 23 - .../grunt-cli/node_modules/nopt/README.md | 208 - .../grunt-cli/node_modules/nopt/bin/nopt.js | 44 - .../node_modules/nopt/examples/my-program.js | 30 - .../grunt-cli/node_modules/nopt/lib/nopt.js | 552 - .../nopt/node_modules/abbrev/CONTRIBUTING.md | 3 - .../nopt/node_modules/abbrev/LICENSE | 23 - .../nopt/node_modules/abbrev/README.md | 23 - .../nopt/node_modules/abbrev/abbrev.js | 62 - .../nopt/node_modules/abbrev/package.json | 46 - .../nopt/node_modules/abbrev/test.js | 47 - .../grunt-cli/node_modules/nopt/package.json | 60 - .../node_modules/resolve/.travis.yml | 4 - .../grunt-cli/node_modules/resolve/LICENSE | 18 - .../node_modules/resolve/example/async.js | 5 - .../node_modules/resolve/example/sync.js | 3 - .../grunt-cli/node_modules/resolve/index.js | 5 - .../node_modules/resolve/lib/async.js | 131 - .../node_modules/resolve/lib/core.js | 4 - .../node_modules/resolve/lib/core.json | 38 - .../node_modules/resolve/lib/sync.js | 99 - .../node_modules/resolve/package.json | 53 - .../node_modules/resolve/readme.markdown | 134 - .../node_modules/resolve/test/core.js | 12 - .../node_modules/resolve/test/filter.js | 17 - .../node_modules/resolve/test/filter_sync.js | 15 - .../node_modules/resolve/test/mock.js | 68 - .../node_modules/resolve/test/mock_sync.js | 68 - .../node_modules/resolve/test/resolver.js | 144 - .../resolver/bar/node_modules/foo/index.js | 1 - .../resolve/test/resolver/baz/doom.js | 0 .../resolve/test/resolver/baz/package.json | 3 - .../resolve/test/resolver/baz/quux.js | 1 - .../resolver/biz/node_modules/grux/index.js | 1 - .../resolver/biz/node_modules/tiv/index.js | 1 - .../resolve/test/resolver/cup.coffee | 1 - .../node_modules/resolve/test/resolver/foo.js | 1 - .../resolve/test/resolver/mug.coffee | 0 .../node_modules/resolve/test/resolver/mug.js | 0 .../test/resolver/other_path/lib/other-lib.js | 0 .../resolve/test/resolver/other_path/root.js | 0 .../resolve/test/resolver_sync.js | 157 - .../node_modules/grunt-cli/package.json | 80 - spec/fixture/node_modules/grunt/.npmignore | 7 - .../node_modules/grunt/CONTRIBUTING.md | 1 - spec/fixture/node_modules/grunt/LICENSE-MIT | 22 - spec/fixture/node_modules/grunt/README.md | 20 - spec/fixture/node_modules/grunt/appveyor.yml | 43 - .../node_modules/grunt/internal-tasks/bump.js | 151 - .../grunt/internal-tasks/subgrunt.js | 34 - spec/fixture/node_modules/grunt/lib/grunt.js | 165 - .../node_modules/grunt/lib/grunt/cli.js | 128 - .../node_modules/grunt/lib/grunt/config.js | 124 - .../node_modules/grunt/lib/grunt/event.js | 16 - .../node_modules/grunt/lib/grunt/fail.js | 84 - .../node_modules/grunt/lib/grunt/file.js | 448 - .../node_modules/grunt/lib/grunt/help.js | 129 - .../node_modules/grunt/lib/grunt/option.js | 42 - .../node_modules/grunt/lib/grunt/task.js | 458 - .../node_modules/grunt/lib/grunt/template.js | 95 - .../node_modules/grunt/lib/util/task.js | 342 - .../node_modules/grunt/node_modules/.bin/cake | 1 - .../grunt/node_modules/.bin/coffee | 1 - .../grunt/node_modules/.bin/js-yaml | 1 - .../node_modules/grunt/node_modules/.bin/nopt | 1 - .../grunt/node_modules/.bin/rimraf | 1 - .../grunt/node_modules/.bin/which | 1 - .../grunt/node_modules/async/.gitmodules | 9 - .../grunt/node_modules/async/.npmignore | 4 - .../grunt/node_modules/async/LICENSE | 19 - .../grunt/node_modules/async/Makefile | 25 - .../grunt/node_modules/async/README.md | 1021 - .../grunt/node_modules/async/index.js | 3 - .../grunt/node_modules/async/lib/async.js | 692 - .../grunt/node_modules/async/package.json | 58 - .../node_modules/coffee-script/.npmignore | 11 - .../grunt/node_modules/coffee-script/CNAME | 1 - .../grunt/node_modules/coffee-script/LICENSE | 22 - .../grunt/node_modules/coffee-script/README | 51 - .../grunt/node_modules/coffee-script/Rakefile | 78 - .../grunt/node_modules/coffee-script/bin/cake | 7 - .../node_modules/coffee-script/bin/coffee | 7 - .../coffee-script/extras/jsl.conf | 44 - .../lib/coffee-script/browser.js | 92 - .../coffee-script/lib/coffee-script/cake.js | 111 - .../lib/coffee-script/coffee-script.js | 167 - .../lib/coffee-script/command.js | 500 - .../lib/coffee-script/grammar.js | 606 - .../lib/coffee-script/helpers.js | 77 - .../coffee-script/lib/coffee-script/index.js | 11 - .../coffee-script/lib/coffee-script/lexer.js | 788 - .../coffee-script/lib/coffee-script/nodes.js | 2986 --- .../lib/coffee-script/optparse.js | 138 - .../coffee-script/lib/coffee-script/parser.js | 683 - .../coffee-script/lib/coffee-script/repl.js | 261 - .../lib/coffee-script/rewriter.js | 349 - .../coffee-script/lib/coffee-script/scope.js | 146 - .../node_modules/coffee-script/package.json | 68 - .../grunt/node_modules/colors/MIT-LICENSE.txt | 22 - .../grunt/node_modules/colors/ReadMe.md | 77 - .../grunt/node_modules/colors/colors.js | 342 - .../grunt/node_modules/colors/example.html | 76 - .../grunt/node_modules/colors/example.js | 77 - .../grunt/node_modules/colors/package.json | 47 - .../grunt/node_modules/colors/test.js | 70 - .../colors/themes/winston-dark.js | 12 - .../colors/themes/winston-light.js | 12 - .../grunt/node_modules/dateformat/Readme.md | 67 - .../node_modules/dateformat/lib/dateformat.js | 165 - .../node_modules/dateformat/package.json | 42 - .../dateformat/test/test_weekofyear.js | 4 - .../dateformat/test/test_weekofyear.sh | 27 - .../node_modules/eventemitter2/README.md | 248 - .../grunt/node_modules/eventemitter2/index.js | 1 - .../eventemitter2/lib/eventemitter2.js | 573 - .../node_modules/eventemitter2/package.json | 83 - .../grunt/node_modules/exit/.jshintrc | 14 - .../grunt/node_modules/exit/.npmignore | 0 .../grunt/node_modules/exit/.travis.yml | 6 - .../grunt/node_modules/exit/Gruntfile.js | 48 - .../grunt/node_modules/exit/LICENSE-MIT | 22 - .../grunt/node_modules/exit/README.md | 75 - .../grunt/node_modules/exit/lib/exit.js | 41 - .../grunt/node_modules/exit/package.json | 69 - .../grunt/node_modules/exit/test/exit_test.js | 121 - .../exit/test/fixtures/10-stderr.txt | 10 - .../exit/test/fixtures/10-stdout-stderr.txt | 20 - .../exit/test/fixtures/10-stdout.txt | 10 - .../exit/test/fixtures/100-stderr.txt | 100 - .../exit/test/fixtures/100-stdout-stderr.txt | 200 - .../exit/test/fixtures/100-stdout.txt | 100 - .../exit/test/fixtures/1000-stderr.txt | 1000 - .../exit/test/fixtures/1000-stdout-stderr.txt | 2000 -- .../exit/test/fixtures/1000-stdout.txt | 1000 - .../exit/test/fixtures/create-files.sh | 8 - .../exit/test/fixtures/log-broken.js | 23 - .../node_modules/exit/test/fixtures/log.js | 25 - .../grunt/node_modules/findup-sync/.jshintrc | 15 - .../grunt/node_modules/findup-sync/.npmignore | 0 .../node_modules/findup-sync/.travis.yml | 5 - .../node_modules/findup-sync/Gruntfile.js | 25 - .../node_modules/findup-sync/LICENSE-MIT | 22 - .../grunt/node_modules/findup-sync/README.md | 45 - .../findup-sync/lib/findup-sync.js | 46 - .../findup-sync/node_modules/glob/.npmignore | 2 - .../findup-sync/node_modules/glob/.travis.yml | 3 - .../findup-sync/node_modules/glob/LICENSE | 27 - .../findup-sync/node_modules/glob/README.md | 250 - .../node_modules/glob/examples/g.js | 9 - .../node_modules/glob/examples/usr-local.js | 9 - .../findup-sync/node_modules/glob/glob.js | 728 - .../glob/node_modules/inherits/LICENSE | 16 - .../glob/node_modules/inherits/README.md | 42 - .../glob/node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../glob/node_modules/inherits/package.json | 51 - .../glob/node_modules/inherits/test.js | 25 - .../glob/node_modules/minimatch/.npmignore | 1 - .../glob/node_modules/minimatch/LICENSE | 23 - .../glob/node_modules/minimatch/README.md | 218 - .../glob/node_modules/minimatch/minimatch.js | 1061 - .../node_modules/lru-cache/.npmignore | 1 - .../node_modules/lru-cache/CONTRIBUTORS | 14 - .../minimatch/node_modules/lru-cache/LICENSE | 23 - .../node_modules/lru-cache/README.md | 97 - .../node_modules/lru-cache/lib/lru-cache.js | 252 - .../node_modules/lru-cache/package.json | 50 - .../node_modules/lru-cache/test/basic.js | 369 - .../node_modules/lru-cache/test/foreach.js | 52 - .../lru-cache/test/memory-leak.js | 50 - .../minimatch/node_modules/sigmund/LICENSE | 27 - .../minimatch/node_modules/sigmund/README.md | 53 - .../minimatch/node_modules/sigmund/bench.js | 283 - .../node_modules/sigmund/package.json | 58 - .../minimatch/node_modules/sigmund/sigmund.js | 39 - .../node_modules/sigmund/test/basic.js | 24 - .../glob/node_modules/minimatch/package.json | 57 - .../glob/node_modules/minimatch/test/basic.js | 399 - .../minimatch/test/brace-expand.js | 33 - .../node_modules/minimatch/test/caching.js | 14 - .../node_modules/minimatch/test/defaults.js | 274 - .../test/extglob-ending-with-state-char.js | 8 - .../node_modules/glob/package.json | 58 - .../node_modules/glob/test/00-setup.js | 176 - .../node_modules/glob/test/bash-comparison.js | 63 - .../node_modules/glob/test/bash-results.json | 351 - .../node_modules/glob/test/cwd-test.js | 55 - .../node_modules/glob/test/globstar-match.js | 19 - .../node_modules/glob/test/mark.js | 118 - .../glob/test/new-glob-optional-options.js | 10 - .../node_modules/glob/test/nocase-nomagic.js | 113 - .../node_modules/glob/test/pause-resume.js | 73 - .../node_modules/glob/test/readme-issue.js | 36 - .../node_modules/glob/test/root-nomount.js | 39 - .../node_modules/glob/test/root.js | 46 - .../node_modules/glob/test/stat.js | 32 - .../node_modules/glob/test/zz-cleanup.js | 11 - .../node_modules/lodash/LICENSE.txt | 22 - .../findup-sync/node_modules/lodash/README.md | 163 - .../node_modules/lodash/dist/lodash.compat.js | 7157 ------ .../lodash/dist/lodash.compat.min.js | 61 - .../node_modules/lodash/dist/lodash.js | 6785 ------ .../node_modules/lodash/dist/lodash.min.js | 56 - .../lodash/dist/lodash.underscore.js | 4979 ---- .../lodash/dist/lodash.underscore.min.js | 39 - .../findup-sync/node_modules/lodash/lodash.js | 7179 ------ .../node_modules/lodash/package.json | 132 - .../node_modules/findup-sync/package.json | 65 - .../findup-sync/test/findup-sync_test.js | 48 - .../findup-sync/test/fixtures/a.txt | 0 .../findup-sync/test/fixtures/a/b/bar.txt | 0 .../findup-sync/test/fixtures/a/foo.txt | 0 .../findup-sync/test/fixtures/aaa.txt | 0 .../grunt/node_modules/getobject/.jshintrc | 15 - .../grunt/node_modules/getobject/.npmignore | 1 - .../grunt/node_modules/getobject/.travis.yml | 6 - .../grunt/node_modules/getobject/Gruntfile.js | 48 - .../grunt/node_modules/getobject/LICENSE-MIT | 22 - .../grunt/node_modules/getobject/README.md | 20 - .../node_modules/getobject/lib/getobject.js | 60 - .../grunt/node_modules/getobject/package.json | 66 - .../getobject/test/namespace_test.js | 51 - .../grunt/node_modules/glob/.npmignore | 2 - .../grunt/node_modules/glob/.travis.yml | 3 - .../grunt/node_modules/glob/LICENSE | 27 - .../grunt/node_modules/glob/README.md | 233 - .../grunt/node_modules/glob/examples/g.js | 9 - .../node_modules/glob/examples/usr-local.js | 9 - .../grunt/node_modules/glob/glob.js | 643 - .../glob/node_modules/graceful-fs/.npmignore | 1 - .../glob/node_modules/graceful-fs/LICENSE | 27 - .../glob/node_modules/graceful-fs/README.md | 33 - .../node_modules/graceful-fs/graceful-fs.js | 442 - .../node_modules/graceful-fs/package.json | 65 - .../node_modules/graceful-fs/test/open.js | 46 - .../node_modules/graceful-fs/test/ulimit.js | 158 - .../glob/node_modules/inherits/README.md | 51 - .../glob/node_modules/inherits/inherits.js | 29 - .../glob/node_modules/inherits/package.json | 46 - .../grunt/node_modules/glob/package.json | 57 - .../grunt/node_modules/glob/test/00-setup.js | 176 - .../node_modules/glob/test/bash-comparison.js | 63 - .../node_modules/glob/test/bash-results.json | 348 - .../grunt/node_modules/glob/test/cwd-test.js | 55 - .../grunt/node_modules/glob/test/mark.js | 74 - .../node_modules/glob/test/nocase-nomagic.js | 113 - .../node_modules/glob/test/pause-resume.js | 73 - .../node_modules/glob/test/root-nomount.js | 39 - .../grunt/node_modules/glob/test/root.js | 46 - .../node_modules/glob/test/zz-cleanup.js | 11 - .../node_modules/grunt-legacy-log/.jshintrc | 14 - .../node_modules/grunt-legacy-log/.npmignore | 1 - .../node_modules/grunt-legacy-log/.travis.yml | 11 - .../grunt-legacy-log/Gruntfile.js | 30 - .../node_modules/grunt-legacy-log/LICENSE-MIT | 22 - .../node_modules/grunt-legacy-log/README.md | 6 - .../node_modules/grunt-legacy-log/examples.js | 26 - .../node_modules/grunt-legacy-log/index.js | 377 - .../node_modules/lodash/LICENSE.txt | 22 - .../node_modules/lodash/README.md | 163 - .../node_modules/lodash/dist/lodash.compat.js | 7157 ------ .../lodash/dist/lodash.compat.min.js | 61 - .../node_modules/lodash/dist/lodash.js | 6785 ------ .../node_modules/lodash/dist/lodash.min.js | 56 - .../lodash/dist/lodash.underscore.js | 4979 ---- .../lodash/dist/lodash.underscore.min.js | 39 - .../node_modules/lodash/lodash.js | 7179 ------ .../node_modules/lodash/package.json | 132 - .../underscore.string/.travis.yml | 8 - .../node_modules/underscore.string/Gemfile | 4 - .../underscore.string/Gemfile.lock | 17 - .../underscore.string/README.markdown | 814 - .../node_modules/underscore.string/Rakefile | 23 - .../underscore.string/component.json | 11 - .../dist/underscore.string.min.js | 1 - .../lib/underscore.string.js | 673 - .../underscore.string/libpeerconnection.log | 0 .../underscore.string/package.json | 98 - .../underscore.string/test/run-qunit.js | 45 - .../underscore.string/test/speed.js | 148 - .../underscore.string/test/strings.js | 685 - .../test/strings_standalone.js | 12 - .../underscore.string/test/test.html | 31 - .../test/test_standalone.html | 18 - .../test/test_underscore/arrays.js | 200 - .../test/test_underscore/chaining.js | 59 - .../test/test_underscore/collections.js | 426 - .../test/test_underscore/functions.js | 259 - .../test/test_underscore/index.html | 45 - .../test/test_underscore/objects.js | 548 - .../test/test_underscore/speed.js | 75 - .../test/test_underscore/utility.js | 249 - .../test/test_underscore/vendor/jquery.js | 9404 ------- .../test/test_underscore/vendor/jslitmus.js | 670 - .../test/test_underscore/vendor/qunit.css | 235 - .../test/test_underscore/vendor/qunit.js | 1977 -- .../underscore.string/test/underscore.js | 1201 - .../grunt-legacy-log/package.json | 76 - .../grunt-legacy-log/test/index.js | 572 - .../node_modules/grunt-legacy-util/.jshintrc | 14 - .../node_modules/grunt-legacy-util/.npmignore | 1 - .../grunt-legacy-util/.travis.yml | 11 - .../grunt-legacy-util/Gruntfile.js | 30 - .../grunt-legacy-util/LICENSE-MIT | 22 - .../node_modules/grunt-legacy-util/README.md | 31 - .../node_modules/grunt-legacy-util/index.js | 202 - .../grunt-legacy-util/package.json | 75 - .../test/fixtures/Gruntfile-execArgv-child.js | 7 - .../test/fixtures/Gruntfile-execArgv.js | 17 - .../test/fixtures/Gruntfile-print-text.js | 8 - .../grunt-legacy-util/test/fixtures/exec.cmd | 1 - .../grunt-legacy-util/test/fixtures/exec.sh | 2 - .../test/fixtures/spawn-multibyte.js | 17 - .../grunt-legacy-util/test/fixtures/spawn.js | 8 - .../grunt-legacy-util/test/index.js | 554 - .../grunt/node_modules/hooker/LICENSE-MIT | 22 - .../grunt/node_modules/hooker/README.md | 186 - .../grunt/node_modules/hooker/child.js | 101 - .../node_modules/hooker/dist/ba-hooker.js | 169 - .../node_modules/hooker/dist/ba-hooker.min.js | 4 - .../grunt/node_modules/hooker/grunt.js | 47 - .../grunt/node_modules/hooker/lib/hooker.js | 174 - .../grunt/node_modules/hooker/package.json | 66 - .../grunt/node_modules/hooker/parent.js | 17 - .../node_modules/hooker/test/hooker_test.js | 435 - .../grunt/node_modules/iconv-lite/.npmignore | 3 - .../grunt/node_modules/iconv-lite/.travis.yml | 5 - .../grunt/node_modules/iconv-lite/LICENSE | 21 - .../grunt/node_modules/iconv-lite/README.md | 72 - .../grunt/node_modules/iconv-lite/README.md~ | 54 - .../node_modules/iconv-lite/encodings/big5.js | 9 - .../node_modules/iconv-lite/encodings/gbk.js | 9 - .../iconv-lite/encodings/singlebyte.js | 340 - .../iconv-lite/encodings/table/big5.js | 1 - .../iconv-lite/encodings/table/gbk.js | 1 - .../generation/generate-big5-table.js | 25 - .../generation/generate-singlebyte.js | 142 - .../grunt/node_modules/iconv-lite/index.js | 231 - .../node_modules/iconv-lite/package.json | 97 - .../node_modules/iconv-lite/test/big5-test.js | 36 - .../node_modules/iconv-lite/test/big5File.txt | 13 - .../iconv-lite/test/cyrillic-test.js | 86 - .../node_modules/iconv-lite/test/gbk-test.js | 38 - .../node_modules/iconv-lite/test/gbkFile.txt | 14 - .../iconv-lite/test/greek-test.js | 79 - .../node_modules/iconv-lite/test/main-test.js | 55 - .../iconv-lite/test/performance.js | 67 - .../iconv-lite/test/turkish-test.js | 90 - .../grunt/node_modules/js-yaml/HISTORY.md | 155 - .../grunt/node_modules/js-yaml/LICENSE | 21 - .../grunt/node_modules/js-yaml/README.md | 249 - .../grunt/node_modules/js-yaml/bin/js-yaml.js | 125 - .../js-yaml/examples/custom_types.js | 104 - .../js-yaml/examples/custom_types.yaml | 18 - .../node_modules/js-yaml/examples/dumper.js | 31 - .../node_modules/js-yaml/examples/dumper.json | 22 - .../js-yaml/examples/sample_document.js | 15 - .../js-yaml/examples/sample_document.yaml | 197 - .../grunt/node_modules/js-yaml/index.js | 1 - .../grunt/node_modules/js-yaml/lib/js-yaml.js | 33 - .../js-yaml/lib/js-yaml/common.js | 60 - .../js-yaml/lib/js-yaml/dumper.js | 437 - .../js-yaml/lib/js-yaml/exception.js | 25 - .../js-yaml/lib/js-yaml/loader.js | 1549 -- .../node_modules/js-yaml/lib/js-yaml/mark.js | 78 - .../js-yaml/lib/js-yaml/require.js | 23 - .../js-yaml/lib/js-yaml/schema.js | 103 - .../js-yaml/lib/js-yaml/schema/default.js | 16 - .../js-yaml/lib/js-yaml/schema/minimal.js | 13 - .../js-yaml/lib/js-yaml/schema/safe.js | 25 - .../node_modules/js-yaml/lib/js-yaml/type.js | 82 - .../js-yaml/lib/js-yaml/type/binary.js | 118 - .../js-yaml/lib/js-yaml/type/bool.js | 74 - .../js-yaml/lib/js-yaml/type/float.js | 102 - .../js-yaml/lib/js-yaml/type/int.js | 85 - .../js-yaml/lib/js-yaml/type/js/function.js | 56 - .../js-yaml/lib/js-yaml/type/js/regexp.js | 56 - .../js-yaml/lib/js-yaml/type/js/undefined.js | 28 - .../js-yaml/lib/js-yaml/type/map.js | 11 - .../js-yaml/lib/js-yaml/type/merge.js | 18 - .../js-yaml/lib/js-yaml/type/null.js | 36 - .../js-yaml/lib/js-yaml/type/omap.js | 53 - .../js-yaml/lib/js-yaml/type/pairs.js | 41 - .../js-yaml/lib/js-yaml/type/seq.js | 11 - .../js-yaml/lib/js-yaml/type/set.js | 31 - .../js-yaml/lib/js-yaml/type/str.js | 11 - .../js-yaml/lib/js-yaml/type/timestamp.js | 91 - .../js-yaml/node_modules/.bin/esparse | 1 - .../js-yaml/node_modules/.bin/esvalidate | 1 - .../js-yaml/node_modules/argparse/HISTORY.md | 109 - .../js-yaml/node_modules/argparse/LICENSE | 21 - .../js-yaml/node_modules/argparse/README.md | 239 - .../argparse/examples/arguments.js | 36 - .../node_modules/argparse/examples/choice.js | 22 - .../argparse/examples/constants.js | 59 - .../node_modules/argparse/examples/help.js | 13 - .../node_modules/argparse/examples/nargs.js | 33 - .../node_modules/argparse/examples/parents.js | 28 - .../argparse/examples/prefix_chars.js | 23 - .../argparse/examples/sub_commands.js | 49 - .../node_modules/argparse/examples/sum.js | 35 - .../argparse/examples/testformatters.js | 270 - .../js-yaml/node_modules/argparse/index.js | 1 - .../node_modules/argparse/lib/action.js | 146 - .../argparse/lib/action/append.js | 55 - .../argparse/lib/action/append/constant.js | 47 - .../node_modules/argparse/lib/action/count.js | 40 - .../node_modules/argparse/lib/action/help.js | 48 - .../node_modules/argparse/lib/action/store.js | 50 - .../argparse/lib/action/store/constant.js | 43 - .../argparse/lib/action/store/false.js | 27 - .../argparse/lib/action/store/true.js | 26 - .../argparse/lib/action/subparsers.js | 148 - .../argparse/lib/action/version.js | 50 - .../argparse/lib/action_container.js | 481 - .../node_modules/argparse/lib/argparse.js | 14 - .../argparse/lib/argument/error.js | 50 - .../argparse/lib/argument/exclusive.js | 54 - .../argparse/lib/argument/group.js | 75 - .../argparse/lib/argument_parser.js | 1165 - .../node_modules/argparse/lib/const.js | 18 - .../argparse/lib/help/added_formatters.js | 88 - .../argparse/lib/help/formatter.js | 803 - .../node_modules/argparse/lib/namespace.js | 77 - .../underscore.string/.travis.yml | 8 - .../node_modules/underscore.string/Gemfile | 4 - .../underscore.string/Gemfile.lock | 17 - .../underscore.string/README.markdown | 814 - .../node_modules/underscore.string/Rakefile | 23 - .../underscore.string/component.json | 11 - .../dist/underscore.string.min.js | 1 - .../lib/underscore.string.js | 673 - .../underscore.string/libpeerconnection.log | 0 .../underscore.string/package.json | 98 - .../underscore.string/test/run-qunit.js | 45 - .../underscore.string/test/speed.js | 148 - .../underscore.string/test/strings.js | 685 - .../test/strings_standalone.js | 12 - .../underscore.string/test/test.html | 31 - .../test/test_standalone.html | 18 - .../test/test_underscore/arrays.js | 200 - .../test/test_underscore/chaining.js | 59 - .../test/test_underscore/collections.js | 426 - .../test/test_underscore/functions.js | 259 - .../test/test_underscore/index.html | 45 - .../test/test_underscore/objects.js | 548 - .../test/test_underscore/speed.js | 75 - .../test/test_underscore/utility.js | 249 - .../test/test_underscore/vendor/jquery.js | 9404 ------- .../test/test_underscore/vendor/jslitmus.js | 670 - .../test/test_underscore/vendor/qunit.css | 235 - .../test/test_underscore/vendor/qunit.js | 1977 -- .../underscore.string/test/underscore.js | 1201 - .../node_modules/underscore/.npmignore | 4 - .../node_modules/underscore/.travis.yml | 5 - .../argparse/node_modules/underscore/CNAME | 1 - .../node_modules/underscore/CONTRIBUTING.md | 9 - .../argparse/node_modules/underscore/LICENSE | 22 - .../node_modules/underscore/README.md | 19 - .../node_modules/underscore/favicon.ico | Bin 1406 -> 0 bytes .../node_modules/underscore/index.html | 2467 -- .../argparse/node_modules/underscore/index.js | 1 - .../node_modules/underscore/package.json | 52 - .../node_modules/underscore/underscore-min.js | 1 - .../node_modules/underscore/underscore.js | 1226 - .../node_modules/argparse/package.json | 68 - .../js-yaml/node_modules/esprima/README.md | 73 - .../node_modules/esprima/bin/esparse.js | 117 - .../node_modules/esprima/bin/esvalidate.js | 177 - .../js-yaml/node_modules/esprima/esprima.js | 3908 --- .../js-yaml/node_modules/esprima/package.json | 69 - .../node_modules/esprima/test/compat.js | 239 - .../node_modules/esprima/test/reflect.js | 422 - .../js-yaml/node_modules/esprima/test/run.js | 66 - .../node_modules/esprima/test/runner.js | 387 - .../js-yaml/node_modules/esprima/test/test.js | 20238 ---------------- .../grunt/node_modules/js-yaml/package.json | 77 - .../grunt/node_modules/lodash/README.md | 140 - .../grunt/node_modules/lodash/lodash.js | 4258 ---- .../grunt/node_modules/lodash/lodash.min.js | 35 - .../node_modules/lodash/lodash.underscore.js | 3688 --- .../lodash/lodash.underscore.min.js | 28 - .../grunt/node_modules/lodash/package.json | 79 - .../grunt/node_modules/minimatch/.npmignore | 1 - .../grunt/node_modules/minimatch/LICENSE | 23 - .../grunt/node_modules/minimatch/README.md | 218 - .../grunt/node_modules/minimatch/minimatch.js | 1055 - .../node_modules/lru-cache/.npmignore | 1 - .../node_modules/lru-cache/CONTRIBUTORS | 14 - .../minimatch/node_modules/lru-cache/LICENSE | 23 - .../node_modules/lru-cache/README.md | 97 - .../node_modules/lru-cache/lib/lru-cache.js | 252 - .../node_modules/lru-cache/package.json | 50 - .../node_modules/lru-cache/test/basic.js | 369 - .../node_modules/lru-cache/test/foreach.js | 52 - .../lru-cache/test/memory-leak.js | 50 - .../minimatch/node_modules/sigmund/LICENSE | 27 - .../minimatch/node_modules/sigmund/README.md | 53 - .../minimatch/node_modules/sigmund/bench.js | 283 - .../node_modules/sigmund/package.json | 58 - .../minimatch/node_modules/sigmund/sigmund.js | 39 - .../node_modules/sigmund/test/basic.js | 24 - .../grunt/node_modules/minimatch/package.json | 57 - .../node_modules/minimatch/test/basic.js | 399 - .../minimatch/test/brace-expand.js | 33 - .../node_modules/minimatch/test/caching.js | 14 - .../node_modules/minimatch/test/defaults.js | 274 - .../test/extglob-ending-with-state-char.js | 8 - .../grunt/node_modules/nopt/.gitignore | 0 .../grunt/node_modules/nopt/LICENSE | 23 - .../grunt/node_modules/nopt/README.md | 208 - .../grunt/node_modules/nopt/bin/nopt.js | 44 - .../node_modules/nopt/examples/my-program.js | 30 - .../grunt/node_modules/nopt/lib/nopt.js | 552 - .../nopt/node_modules/abbrev/CONTRIBUTING.md | 3 - .../nopt/node_modules/abbrev/LICENSE | 23 - .../nopt/node_modules/abbrev/README.md | 23 - .../nopt/node_modules/abbrev/abbrev.js | 62 - .../nopt/node_modules/abbrev/package.json | 46 - .../nopt/node_modules/abbrev/test.js | 47 - .../grunt/node_modules/nopt/package.json | 60 - .../grunt/node_modules/rimraf/AUTHORS | 6 - .../grunt/node_modules/rimraf/LICENSE | 23 - .../grunt/node_modules/rimraf/README.md | 30 - .../grunt/node_modules/rimraf/bin.js | 33 - .../grunt/node_modules/rimraf/package.json | 73 - .../grunt/node_modules/rimraf/rimraf.js | 248 - .../grunt/node_modules/rimraf/test/run.sh | 16 - .../grunt/node_modules/rimraf/test/setup.sh | 47 - .../node_modules/rimraf/test/test-async.js | 5 - .../node_modules/rimraf/test/test-sync.js | 3 - .../underscore.string/.travis.yml | 8 - .../node_modules/underscore.string/Gemfile | 5 - .../underscore.string/Gemfile.lock | 34 - .../underscore.string/README.markdown | 668 - .../node_modules/underscore.string/Rakefile | 28 - .../dist/underscore.string.min.js | 1 - .../lib/underscore.string.js | 525 - .../underscore.string/package.json | 96 - .../underscore.string/test/run-qunit.js | 44 - .../underscore.string/test/speed.js | 138 - .../underscore.string/test/strings.js | 438 - .../test/strings_standalone.js | 12 - .../underscore.string/test/test.html | 31 - .../test/test_standalone.html | 18 - .../test/test_underscore/arrays.js | 166 - .../test/test_underscore/chaining.js | 59 - .../test/test_underscore/collections.js | 270 - .../test/test_underscore/functions.js | 198 - .../test/test_underscore/objects.js | 535 - .../test/test_underscore/speed.js | 70 - .../test/test_underscore/temp.js | 27 - .../test/test_underscore/temp_tests.html | 19 - .../test/test_underscore/test.html | 43 - .../test/test_underscore/utility.js | 155 - .../test/test_underscore/vendor/jquery.js | 19 - .../test/test_underscore/vendor/jslitmus.js | 670 - .../test/test_underscore/vendor/qunit.css | 196 - .../test/test_underscore/vendor/qunit.js | 2360 -- .../underscore.string/test/underscore.js | 999 - .../grunt/node_modules/which/LICENSE | 23 - .../grunt/node_modules/which/README.md | 5 - .../grunt/node_modules/which/bin/which | 14 - .../grunt/node_modules/which/package.json | 53 - .../grunt/node_modules/which/which.js | 104 - spec/fixture/node_modules/grunt/package.json | 105 - spec/fixture/node_modules/gulp/README.md | 100 - spec/fixture/node_modules/gulp/bin/gulp.js | 212 - .../node_modules/gulp/completion/README.md | 20 - .../fixture/node_modules/gulp/completion/bash | 27 - .../fixture/node_modules/gulp/completion/fish | 10 - .../node_modules/gulp/completion/powershell | 61 - spec/fixture/node_modules/gulp/completion/zsh | 25 - spec/fixture/node_modules/gulp/index.js | 63 - .../node_modules/gulp/lib/completion.js | 22 - .../fixture/node_modules/gulp/lib/taskTree.js | 14 - .../gulp/node_modules/.bin/semver | 1 - .../gulp/node_modules/archy/.travis.yml | 4 - .../gulp/node_modules/archy/README.markdown | 92 - .../gulp/node_modules/archy/examples/beep.js | 24 - .../node_modules/archy/examples/multi_line.js | 25 - .../gulp/node_modules/archy/index.js | 35 - .../gulp/node_modules/archy/package.json | 68 - .../gulp/node_modules/archy/test/beep.js | 40 - .../node_modules/archy/test/multi_line.js | 45 - .../node_modules/archy/test/non_unicode.js | 40 - .../gulp/node_modules/chalk/index.js | 95 - .../chalk/node_modules/.bin/has-ansi | 1 - .../chalk/node_modules/.bin/strip-ansi | 1 - .../chalk/node_modules/.bin/supports-color | 1 - .../chalk/node_modules/ansi-styles/index.js | 40 - .../node_modules/ansi-styles/package.json | 74 - .../chalk/node_modules/ansi-styles/readme.md | 70 - .../escape-string-regexp/index.js | 11 - .../escape-string-regexp/package.json | 69 - .../escape-string-regexp/readme.md | 27 - .../chalk/node_modules/has-ansi/cli.js | 53 - .../chalk/node_modules/has-ansi/index.js | 4 - .../has-ansi/node_modules/ansi-regex/index.js | 4 - .../node_modules/ansi-regex/package.json | 79 - .../node_modules/ansi-regex/readme.md | 33 - .../chalk/node_modules/has-ansi/package.json | 85 - .../chalk/node_modules/has-ansi/readme.md | 45 - .../chalk/node_modules/strip-ansi/cli.js | 39 - .../chalk/node_modules/strip-ansi/index.js | 6 - .../node_modules/ansi-regex/index.js | 4 - .../node_modules/ansi-regex/package.json | 79 - .../node_modules/ansi-regex/readme.md | 33 - .../node_modules/strip-ansi/package.json | 84 - .../chalk/node_modules/strip-ansi/readme.md | 43 - .../chalk/node_modules/supports-color/cli.js | 28 - .../node_modules/supports-color/index.js | 32 - .../node_modules/supports-color/package.json | 78 - .../node_modules/supports-color/readme.md | 44 - .../gulp/node_modules/chalk/package.json | 82 - .../gulp/node_modules/chalk/readme.md | 175 - .../gulp/node_modules/deprecated/.npmignore | 6 - .../gulp/node_modules/deprecated/.travis.yml | 6 - .../gulp/node_modules/deprecated/LICENSE | 20 - .../gulp/node_modules/deprecated/README.md | 51 - .../gulp/node_modules/deprecated/index.js | 39 - .../gulp/node_modules/deprecated/package.json | 63 - .../node_modules/deprecated/test/field.js | 44 - .../node_modules/deprecated/test/method.js | 32 - .../gulp/node_modules/gulp-util/.npmignore | 7 - .../gulp/node_modules/gulp-util/.travis.yml | 5 - .../gulp/node_modules/gulp-util/LICENSE | 20 - .../gulp/node_modules/gulp-util/README.md | 141 - .../gulp/node_modules/gulp-util/index.js | 18 - .../gulp/node_modules/gulp-util/lib/File.js | 1 - .../node_modules/gulp-util/lib/PluginError.js | 120 - .../gulp/node_modules/gulp-util/lib/beep.js | 3 - .../gulp/node_modules/gulp-util/lib/buffer.js | 15 - .../gulp/node_modules/gulp-util/lib/colors.js | 1 - .../node_modules/gulp-util/lib/combine.js | 11 - .../gulp/node_modules/gulp-util/lib/date.js | 1 - .../gulp/node_modules/gulp-util/lib/env.js | 4 - .../node_modules/gulp-util/lib/isBuffer.js | 7 - .../gulp/node_modules/gulp-util/lib/isNull.js | 3 - .../node_modules/gulp-util/lib/isStream.js | 5 - .../node_modules/gulp-util/lib/linefeed.js | 1 - .../gulp/node_modules/gulp-util/lib/log.js | 10 - .../gulp/node_modules/gulp-util/lib/noop.js | 5 - .../gulp-util/lib/replaceExtension.js | 9 - .../node_modules/gulp-util/lib/template.js | 19 - .../gulp-util/node_modules/dateformat/LICENSE | 20 - .../node_modules/dateformat/Readme.md | 79 - .../node_modules/dateformat/lib/dateformat.js | 183 - .../node_modules/dateformat/package.json | 60 - .../dateformat/test/test_dayofweek.js | 10 - .../dateformat/test/test_weekofyear.js | 4 - .../dateformat/test/test_weekofyear.sh | 27 - .../lodash._reinterpolate/LICENSE.txt | 22 - .../lodash._reinterpolate/README.md | 15 - .../lodash._reinterpolate/index.js | 13 - .../lodash._reinterpolate/package.json | 75 - .../node_modules/lodash.template/LICENSE.txt | 22 - .../node_modules/lodash.template/README.md | 15 - .../node_modules/lodash.template/index.js | 216 - .../lodash._escapestringchar/LICENSE.txt | 22 - .../lodash._escapestringchar/README.md | 15 - .../lodash._escapestringchar/index.js | 33 - .../lodash._escapestringchar/package.json | 75 - .../node_modules/lodash.defaults/LICENSE.txt | 22 - .../node_modules/lodash.defaults/README.md | 15 - .../node_modules/lodash.defaults/index.js | 54 - .../lodash._objecttypes/LICENSE.txt | 22 - .../lodash._objecttypes/README.md | 15 - .../node_modules/lodash._objecttypes/index.js | 20 - .../lodash._objecttypes/package.json | 76 - .../node_modules/lodash.defaults/package.json | 86 - .../node_modules/lodash.escape/LICENSE.txt | 22 - .../node_modules/lodash.escape/README.md | 15 - .../node_modules/lodash.escape/index.js | 31 - .../lodash._escapehtmlchar/LICENSE.txt | 22 - .../lodash._escapehtmlchar/README.md | 15 - .../lodash._escapehtmlchar/index.js | 22 - .../lodash._htmlescapes/LICENSE.txt | 22 - .../lodash._htmlescapes/README.md | 15 - .../node_modules/lodash._htmlescapes/index.js | 26 - .../lodash._htmlescapes/package.json | 75 - .../lodash._escapehtmlchar/package.json | 78 - .../lodash._reunescapedhtml/LICENSE.txt | 22 - .../lodash._reunescapedhtml/README.md | 15 - .../lodash._reunescapedhtml/index.js | 15 - .../lodash._htmlescapes/LICENSE.txt | 22 - .../lodash._htmlescapes/README.md | 15 - .../node_modules/lodash._htmlescapes/index.js | 26 - .../lodash._htmlescapes/package.json | 75 - .../lodash._reunescapedhtml/package.json | 79 - .../node_modules/lodash.escape/package.json | 87 - .../node_modules/lodash.keys/LICENSE.txt | 22 - .../node_modules/lodash.keys/README.md | 15 - .../node_modules/lodash.keys/index.js | 36 - .../node_modules/lodash._isnative/LICENSE.txt | 22 - .../node_modules/lodash._isnative/README.md | 15 - .../node_modules/lodash._isnative/index.js | 34 - .../lodash._isnative/package.json | 63 - .../node_modules/lodash._shimkeys/LICENSE.txt | 22 - .../node_modules/lodash._shimkeys/README.md | 15 - .../node_modules/lodash._shimkeys/index.js | 38 - .../lodash._objecttypes/LICENSE.txt | 22 - .../lodash._objecttypes/README.md | 15 - .../node_modules/lodash._objecttypes/index.js | 20 - .../lodash._objecttypes/package.json | 76 - .../lodash._shimkeys/package.json | 78 - .../node_modules/lodash.isobject/LICENSE.txt | 22 - .../node_modules/lodash.isobject/README.md | 15 - .../node_modules/lodash.isobject/index.js | 39 - .../lodash._objecttypes/LICENSE.txt | 22 - .../lodash._objecttypes/README.md | 15 - .../node_modules/lodash._objecttypes/index.js | 20 - .../lodash._objecttypes/package.json | 76 - .../node_modules/lodash.isobject/package.json | 85 - .../node_modules/lodash.keys/package.json | 87 - .../lodash.templatesettings/LICENSE.txt | 22 - .../lodash.templatesettings/README.md | 15 - .../lodash.templatesettings/index.js | 73 - .../lodash.templatesettings/package.json | 86 - .../node_modules/lodash.values/LICENSE.txt | 22 - .../node_modules/lodash.values/README.md | 15 - .../node_modules/lodash.values/index.js | 36 - .../node_modules/lodash.values/package.json | 85 - .../node_modules/lodash.template/package.json | 91 - .../gulp-util/node_modules/lodash/LICENSE.txt | 22 - .../gulp-util/node_modules/lodash/README.md | 163 - .../node_modules/lodash/dist/lodash.compat.js | 7157 ------ .../lodash/dist/lodash.compat.min.js | 61 - .../node_modules/lodash/dist/lodash.js | 6785 ------ .../node_modules/lodash/dist/lodash.min.js | 56 - .../lodash/dist/lodash.underscore.js | 4979 ---- .../lodash/dist/lodash.underscore.min.js | 39 - .../gulp-util/node_modules/lodash/lodash.js | 7179 ------ .../node_modules/lodash/package.json | 132 - .../node_modules/multipipe/.npmignore | 1 - .../node_modules/multipipe/.travis.yml | 3 - .../node_modules/multipipe/History.md | 25 - .../gulp-util/node_modules/multipipe/Makefile | 10 - .../node_modules/multipipe/Readme.md | 101 - .../gulp-util/node_modules/multipipe/index.js | 72 - .../node_modules/duplexer2/.npmignore | 1 - .../node_modules/duplexer2/.travis.yml | 3 - .../node_modules/duplexer2/LICENSE.md | 26 - .../node_modules/duplexer2/README.md | 129 - .../node_modules/duplexer2/example.js | 49 - .../multipipe/node_modules/duplexer2/index.js | 62 - .../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/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 | 54 - .../node_modules/core-util-is/util.js | 106 - .../node_modules/inherits/LICENSE | 16 - .../node_modules/inherits/README.md | 42 - .../node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../node_modules/inherits/package.json | 51 - .../node_modules/inherits/test.js | 25 - .../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 | 54 - .../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/readable-stream/package.json | 70 - .../readable-stream/passthrough.js | 1 - .../node_modules/readable-stream/readable.js | 7 - .../node_modules/readable-stream/transform.js | 1 - .../node_modules/readable-stream/writable.js | 1 - .../node_modules/duplexer2/package.json | 57 - .../node_modules/duplexer2/test/tests.js | 161 - .../node_modules/multipipe/package.json | 43 - .../node_modules/multipipe/test/multipipe.js | 141 - .../node_modules/through2/.npmignore | 3 - .../gulp-util/node_modules/through2/LICENSE | 39 - .../gulp-util/node_modules/through2/README.md | 149 - .../node_modules/readable-stream/.npmignore | 5 - .../node_modules/readable-stream/LICENSE | 27 - .../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/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 | 54 - .../node_modules/core-util-is/util.js | 106 - .../node_modules/inherits/LICENSE | 16 - .../node_modules/inherits/README.md | 42 - .../node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../node_modules/inherits/package.json | 51 - .../node_modules/inherits/test.js | 25 - .../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 | 54 - .../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/readable-stream/package.json | 70 - .../readable-stream/passthrough.js | 1 - .../node_modules/readable-stream/readable.js | 7 - .../node_modules/readable-stream/transform.js | 1 - .../node_modules/readable-stream/writable.js | 1 - .../through2/node_modules/xtend/.jshintrc | 30 - .../through2/node_modules/xtend/.npmignore | 1 - .../through2/node_modules/xtend/LICENCE | 19 - .../through2/node_modules/xtend/Makefile | 4 - .../through2/node_modules/xtend/README.md | 32 - .../through2/node_modules/xtend/immutable.js | 17 - .../through2/node_modules/xtend/mutable.js | 15 - .../through2/node_modules/xtend/package.json | 88 - .../through2/node_modules/xtend/test.js | 63 - .../node_modules/through2/package.json | 65 - .../node_modules/through2/through2.js | 96 - .../node_modules/vinyl/.jshintignore | 2 - .../gulp-util/node_modules/vinyl/.jshintrc | 36 - .../gulp-util/node_modules/vinyl/.npmignore | 6 - .../gulp-util/node_modules/vinyl/.travis.yml | 5 - .../gulp-util/node_modules/vinyl/LICENSE | 20 - .../gulp-util/node_modules/vinyl/README.md | 127 - .../node_modules/vinyl/coverage/coverage.json | 1 - .../vinyl/coverage/lcov-report/index.html | 363 - .../vinyl/coverage/lcov-report/prettify.css | 1 - .../vinyl/coverage/lcov-report/prettify.js | 1 - .../coverage/lcov-report/vinyl/index.html | 350 - .../coverage/lcov-report/vinyl/index.js.html | 847 - .../lcov-report/vinyl/lib/cloneBuffer.js.html | 343 - .../coverage/lcov-report/vinyl/lib/index.html | 402 - .../vinyl/lib/inspectStream.js.html | 355 - .../lcov-report/vinyl/lib/isBuffer.js.html | 340 - .../lcov-report/vinyl/lib/isNull.js.html | 331 - .../lcov-report/vinyl/lib/isStream.js.html | 334 - .../node_modules/vinyl/coverage/lcov.info | 280 - .../gulp-util/node_modules/vinyl/index.js | 175 - .../node_modules/vinyl/lib/cloneBuffer.js | 7 - .../node_modules/vinyl/lib/inspectStream.js | 11 - .../node_modules/vinyl/lib/isBuffer.js | 7 - .../node_modules/vinyl/lib/isNull.js | 3 - .../node_modules/vinyl/lib/isStream.js | 5 - .../vinyl/node_modules/clone-stats/LICENSE.md | 21 - .../vinyl/node_modules/clone-stats/README.md | 17 - .../vinyl/node_modules/clone-stats/index.js | 13 - .../node_modules/clone-stats/package.json | 57 - .../vinyl/node_modules/clone-stats/test.js | 36 - .../gulp-util/node_modules/vinyl/package.json | 70 - .../node_modules/vinyl/perf/clone.js | 59 - .../gulp-util/node_modules/vinyl/test/File.js | 753 - .../node_modules/vinyl/test/cloneBuffer.js | 27 - .../node_modules/vinyl/test/inspectStream.js | 53 - .../node_modules/vinyl/test/isBuffer.js | 29 - .../node_modules/vinyl/test/isNull.js | 22 - .../node_modules/vinyl/test/isStream.js | 29 - .../gulp/node_modules/gulp-util/package.json | 77 - .../gulp/node_modules/interpret/CHANGELOG | 32 - .../gulp/node_modules/interpret/LICENSE | 22 - .../gulp/node_modules/interpret/README.md | 61 - .../gulp/node_modules/interpret/index.js | 48 - .../gulp/node_modules/interpret/package.json | 62 - .../gulp/node_modules/liftoff/.jshintrc | 11 - .../gulp/node_modules/liftoff/.npmignore | 1 - .../gulp/node_modules/liftoff/.travis.yml | 9 - .../gulp/node_modules/liftoff/CHANGELOG | 87 - .../gulp/node_modules/liftoff/LICENSE | 22 - .../gulp/node_modules/liftoff/README.md | 301 - .../gulp/node_modules/liftoff/UPGRADING.md | 26 - .../gulp/node_modules/liftoff/appveyor.yml | 28 - .../liftoff/artwork/liftoff-icon.eps | Bin 520682 -> 0 bytes .../liftoff/artwork/liftoff-icon.png | Bin 8407 -> 0 bytes .../liftoff/artwork/liftoff-icon.svg | 77 - .../node_modules/liftoff/artwork/liftoff.eps | Bin 551958 -> 0 bytes .../node_modules/liftoff/artwork/liftoff.png | Bin 10492 -> 0 bytes .../node_modules/liftoff/artwork/liftoff.svg | 78 - .../gulp/node_modules/liftoff/index.js | 168 - .../liftoff/lib/build_config_name.js | 17 - .../node_modules/liftoff/lib/file_search.js | 14 - .../node_modules/liftoff/lib/find_config.js | 25 - .../gulp/node_modules/liftoff/lib/find_cwd.js | 16 - .../node_modules/liftoff/lib/parse_options.js | 33 - .../liftoff/lib/silent_require.js | 5 - .../liftoff/node_modules/extend/.npmignore | 1 - .../liftoff/node_modules/extend/.travis.yml | 18 - .../liftoff/node_modules/extend/LICENSE | 23 - .../liftoff/node_modules/extend/README.md | 60 - .../node_modules/extend/component.json | 31 - .../liftoff/node_modules/extend/index.js | 80 - .../liftoff/node_modules/extend/package.json | 66 - .../node_modules/findup-sync/.jshintrc | 15 - .../node_modules/findup-sync/.npmignore | 0 .../node_modules/findup-sync/.travis.yml | 5 - .../node_modules/findup-sync/Gruntfile.js | 25 - .../node_modules/findup-sync/LICENSE-MIT | 22 - .../node_modules/findup-sync/README.md | 45 - .../findup-sync/lib/findup-sync.js | 46 - .../findup-sync/node_modules/glob/.npmignore | 2 - .../findup-sync/node_modules/glob/.travis.yml | 3 - .../findup-sync/node_modules/glob/LICENSE | 27 - .../findup-sync/node_modules/glob/README.md | 250 - .../node_modules/glob/examples/g.js | 9 - .../node_modules/glob/examples/usr-local.js | 9 - .../findup-sync/node_modules/glob/glob.js | 728 - .../glob/node_modules/inherits/LICENSE | 16 - .../glob/node_modules/inherits/README.md | 42 - .../glob/node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../glob/node_modules/inherits/package.json | 51 - .../glob/node_modules/inherits/test.js | 25 - .../glob/node_modules/minimatch/.npmignore | 1 - .../glob/node_modules/minimatch/LICENSE | 23 - .../glob/node_modules/minimatch/README.md | 218 - .../glob/node_modules/minimatch/minimatch.js | 1061 - .../node_modules/lru-cache/.npmignore | 1 - .../node_modules/lru-cache/CONTRIBUTORS | 14 - .../minimatch/node_modules/lru-cache/LICENSE | 23 - .../node_modules/lru-cache/README.md | 97 - .../node_modules/lru-cache/lib/lru-cache.js | 252 - .../node_modules/lru-cache/package.json | 50 - .../node_modules/lru-cache/test/basic.js | 369 - .../node_modules/lru-cache/test/foreach.js | 52 - .../lru-cache/test/memory-leak.js | 50 - .../minimatch/node_modules/sigmund/LICENSE | 27 - .../minimatch/node_modules/sigmund/README.md | 53 - .../minimatch/node_modules/sigmund/bench.js | 283 - .../node_modules/sigmund/package.json | 58 - .../minimatch/node_modules/sigmund/sigmund.js | 39 - .../node_modules/sigmund/test/basic.js | 24 - .../glob/node_modules/minimatch/package.json | 57 - .../glob/node_modules/minimatch/test/basic.js | 399 - .../minimatch/test/brace-expand.js | 33 - .../node_modules/minimatch/test/caching.js | 14 - .../node_modules/minimatch/test/defaults.js | 274 - .../test/extglob-ending-with-state-char.js | 8 - .../node_modules/glob/package.json | 58 - .../node_modules/glob/test/00-setup.js | 176 - .../node_modules/glob/test/bash-comparison.js | 63 - .../node_modules/glob/test/bash-results.json | 351 - .../node_modules/glob/test/cwd-test.js | 55 - .../node_modules/glob/test/globstar-match.js | 19 - .../node_modules/glob/test/mark.js | 118 - .../glob/test/new-glob-optional-options.js | 10 - .../node_modules/glob/test/nocase-nomagic.js | 113 - .../node_modules/glob/test/pause-resume.js | 73 - .../node_modules/glob/test/readme-issue.js | 36 - .../node_modules/glob/test/root-nomount.js | 39 - .../node_modules/glob/test/root.js | 46 - .../node_modules/glob/test/stat.js | 32 - .../node_modules/glob/test/zz-cleanup.js | 11 - .../node_modules/lodash/LICENSE.txt | 22 - .../findup-sync/node_modules/lodash/README.md | 163 - .../node_modules/lodash/dist/lodash.compat.js | 7157 ------ .../lodash/dist/lodash.compat.min.js | 61 - .../node_modules/lodash/dist/lodash.js | 6785 ------ .../node_modules/lodash/dist/lodash.min.js | 56 - .../lodash/dist/lodash.underscore.js | 4979 ---- .../lodash/dist/lodash.underscore.min.js | 39 - .../findup-sync/node_modules/lodash/lodash.js | 7179 ------ .../node_modules/lodash/package.json | 132 - .../node_modules/findup-sync/package.json | 65 - .../findup-sync/test/findup-sync_test.js | 48 - .../findup-sync/test/fixtures/a.txt | 0 .../findup-sync/test/fixtures/a/b/bar.txt | 0 .../findup-sync/test/fixtures/a/foo.txt | 0 .../findup-sync/test/fixtures/aaa.txt | 0 .../node_modules/flagged-respawn/.npmignore | 1 - .../node_modules/flagged-respawn/.travis.yml | 9 - .../node_modules/flagged-respawn/LICENSE | 22 - .../node_modules/flagged-respawn/README.md | 57 - .../node_modules/flagged-respawn/index.js | 18 - .../flagged-respawn/lib/reorder.js | 16 - .../flagged-respawn/lib/respawn.js | 15 - .../node_modules/flagged-respawn/package.json | 62 - .../flagged-respawn/test/bin/exit_code.js | 13 - .../flagged-respawn/test/bin/respawner.js | 17 - .../flagged-respawn/test/bin/signal.js | 16 - .../flagged-respawn/test/index.js | 93 - .../liftoff/node_modules/resolve/.travis.yml | 4 - .../liftoff/node_modules/resolve/LICENSE | 18 - .../node_modules/resolve/example/async.js | 5 - .../node_modules/resolve/example/sync.js | 3 - .../liftoff/node_modules/resolve/index.js | 5 - .../liftoff/node_modules/resolve/lib/async.js | 133 - .../node_modules/resolve/lib/caller.js | 8 - .../liftoff/node_modules/resolve/lib/core.js | 4 - .../node_modules/resolve/lib/core.json | 38 - .../resolve/lib/node-modules-paths.js | 36 - .../liftoff/node_modules/resolve/lib/sync.js | 81 - .../liftoff/node_modules/resolve/package.json | 54 - .../node_modules/resolve/readme.markdown | 144 - .../liftoff/node_modules/resolve/test/core.js | 12 - .../node_modules/resolve/test/dotdot.js | 29 - .../resolve/test/dotdot/abc/index.js | 2 - .../node_modules/resolve/test/dotdot/index.js | 1 - .../resolve/test/faulty_basedir.js | 14 - .../node_modules/resolve/test/filter.js | 18 - .../node_modules/resolve/test/filter_sync.js | 15 - .../liftoff/node_modules/resolve/test/mock.js | 142 - .../node_modules/resolve/test/mock_sync.js | 68 - .../node_modules/resolve/test/module_dir.js | 56 - .../test/module_dir/xmodules/aaa/index.js | 1 - .../test/module_dir/ymodules/aaa/index.js | 1 - .../test/module_dir/zmodules/bbb/main.js | 1 - .../test/module_dir/zmodules/bbb/package.json | 3 - .../node_modules/resolve/test/node_path.js | 48 - .../resolve/test/node_path/x/aaa/index.js | 1 - .../resolve/test/node_path/x/ccc/index.js | 1 - .../resolve/test/node_path/y/bbb/index.js | 1 - .../resolve/test/node_path/y/ccc/index.js | 1 - .../node_modules/resolve/test/nonstring.js | 9 - .../node_modules/resolve/test/resolver.js | 281 - .../resolver/bar/node_modules/foo/index.js | 1 - .../resolve/test/resolver/baz/doom.js | 0 .../resolve/test/resolver/baz/package.json | 3 - .../resolve/test/resolver/baz/quux.js | 1 - .../biz/node_modules/garply/lib/index.js | 1 - .../biz/node_modules/garply/package.json | 3 - .../resolver/biz/node_modules/grux/index.js | 1 - .../resolver/biz/node_modules/tiv/index.js | 1 - .../resolve/test/resolver/cup.coffee | 1 - .../node_modules/resolve/test/resolver/foo.js | 1 - .../test/resolver/incorrect_main/index.js | 2 - .../test/resolver/incorrect_main/package.json | 3 - .../resolve/test/resolver/mug.coffee | 0 .../node_modules/resolve/test/resolver/mug.js | 0 .../test/resolver/other_path/lib/other-lib.js | 0 .../resolve/test/resolver/other_path/root.js | 0 .../punycode/node_modules/punycode/index.js | 0 .../resolve/test/resolver/quux/foo/index.js | 1 - .../test/resolver/without_basedir/main.js | 6 - .../without_basedir/node_modules/mymodule.js | 1 - .../resolve/test/resolver_sync.js | 180 - .../gulp/node_modules/liftoff/package.json | 68 - .../gulp/node_modules/minimist/.travis.yml | 4 - .../gulp/node_modules/minimist/LICENSE | 18 - .../node_modules/minimist/example/parse.js | 2 - .../gulp/node_modules/minimist/index.js | 219 - .../gulp/node_modules/minimist/package.json | 70 - .../node_modules/minimist/readme.markdown | 91 - .../node_modules/minimist/test/all_bool.js | 32 - .../gulp/node_modules/minimist/test/bool.js | 119 - .../gulp/node_modules/minimist/test/dash.js | 31 - .../minimist/test/default_bool.js | 20 - .../gulp/node_modules/minimist/test/dotted.js | 22 - .../gulp/node_modules/minimist/test/long.js | 31 - .../gulp/node_modules/minimist/test/num.js | 36 - .../gulp/node_modules/minimist/test/parse.js | 197 - .../minimist/test/parse_modified.js | 9 - .../gulp/node_modules/minimist/test/short.js | 67 - .../node_modules/minimist/test/stop_early.js | 15 - .../node_modules/minimist/test/unknown.js | 102 - .../node_modules/minimist/test/whitespace.js | 8 - .../gulp/node_modules/orchestrator/.npmignore | 10 - .../gulp/node_modules/orchestrator/LICENSE | 20 - .../gulp/node_modules/orchestrator/README.md | 286 - .../gulp/node_modules/orchestrator/index.js | 304 - .../node_modules/orchestrator/lib/runTask.js | 66 - .../node_modules/end-of-stream/.npmignore | 1 - .../node_modules/end-of-stream/README.md | 47 - .../node_modules/end-of-stream/index.js | 61 - .../end-of-stream/node_modules/once/LICENSE | 27 - .../end-of-stream/node_modules/once/README.md | 51 - .../once/node_modules/wrappy/LICENSE | 15 - .../once/node_modules/wrappy/README.md | 36 - .../once/node_modules/wrappy/package.json | 52 - .../once/node_modules/wrappy/test/basic.js | 51 - .../once/node_modules/wrappy/wrappy.js | 33 - .../end-of-stream/node_modules/once/once.js | 21 - .../node_modules/once/package.json | 60 - .../node_modules/once/test/once.js | 23 - .../node_modules/end-of-stream/package.json | 55 - .../node_modules/end-of-stream/test.js | 59 - .../node_modules/sequencify/.npmignore | 9 - .../node_modules/sequencify/.travis.yml | 6 - .../node_modules/sequencify/LICENSE | 20 - .../node_modules/sequencify/README.md | 68 - .../node_modules/sequencify/index.js | 46 - .../node_modules/sequencify/package.json | 62 - .../node_modules/stream-consume/.npmignore | 1 - .../node_modules/stream-consume/README.md | 53 - .../node_modules/stream-consume/index.js | 14 - .../node_modules/stream-consume/package.json | 48 - .../node_modules/stream-consume/test/tests.js | 180 - .../node_modules/orchestrator/package.json | 81 - .../node_modules/pretty-hrtime/.npmignore | 10 - .../gulp/node_modules/pretty-hrtime/LICENSE | 20 - .../gulp/node_modules/pretty-hrtime/README.md | 57 - .../gulp/node_modules/pretty-hrtime/index.js | 73 - .../node_modules/pretty-hrtime/package.json | 60 - .../gulp/node_modules/semver/.npmignore | 1 - .../gulp/node_modules/semver/LICENSE | 27 - .../gulp/node_modules/semver/Makefile | 24 - .../gulp/node_modules/semver/README.md | 158 - .../gulp/node_modules/semver/bin/semver | 125 - .../gulp/node_modules/semver/foot.js | 6 - .../gulp/node_modules/semver/head.js | 2 - .../gulp/node_modules/semver/package.json | 50 - .../node_modules/semver/semver.browser.js | 1035 - .../node_modules/semver/semver.browser.js.gz | Bin 7247 -> 0 bytes .../gulp/node_modules/semver/semver.js | 1039 - .../gulp/node_modules/semver/semver.min.js | 1 - .../gulp/node_modules/semver/semver.min.js.gz | Bin 3318 -> 0 bytes .../gulp/node_modules/semver/test/amd.js | 15 - .../gulp/node_modules/semver/test/clean.js | 25 - .../gulp/node_modules/semver/test/gtr.js | 173 - .../gulp/node_modules/semver/test/index.js | 588 - .../gulp/node_modules/semver/test/ltr.js | 175 - .../node_modules/semver/test/no-module.js | 19 - .../gulp/node_modules/tildify/index.js | 6 - .../tildify/node_modules/.bin/user-home | 1 - .../tildify/node_modules/user-home/cli.js | 26 - .../tildify/node_modules/user-home/index.js | 14 - .../node_modules/user-home/package.json | 69 - .../tildify/node_modules/user-home/readme.md | 40 - .../gulp/node_modules/tildify/package.json | 67 - .../gulp/node_modules/tildify/readme.md | 30 - .../gulp/node_modules/v8flags/.npmignore | 1 - .../gulp/node_modules/v8flags/.travis.yml | 9 - .../node_modules/v8flags/3.14.5.9.flags.json | 1 - .../gulp/node_modules/v8flags/LICENSE | 22 - .../gulp/node_modules/v8flags/README.md | 27 - .../gulp/node_modules/v8flags/fetch.js | 30 - .../gulp/node_modules/v8flags/index.js | 1 - .../gulp/node_modules/v8flags/package.json | 60 - .../gulp/node_modules/v8flags/test.js | 22 - .../gulp/node_modules/vinyl-fs/.editorconfig | 10 - .../gulp/node_modules/vinyl-fs/.jshintrc | 27 - .../gulp/node_modules/vinyl-fs/.npmignore | 9 - .../gulp/node_modules/vinyl-fs/.travis.yml | 6 - .../gulp/node_modules/vinyl-fs/LICENSE | 20 - .../gulp/node_modules/vinyl-fs/README.md | 93 - .../gulp/node_modules/vinyl-fs/index.js | 7 - .../node_modules/vinyl-fs/lib/dest/index.js | 66 - .../vinyl-fs/lib/dest/writeContents/index.js | 59 - .../lib/dest/writeContents/writeBuffer.js | 13 - .../lib/dest/writeContents/writeDir.js | 9 - .../lib/dest/writeContents/writeStream.js | 22 - .../lib/src/getContents/bufferFile.js | 16 - .../vinyl-fs/lib/src/getContents/index.js | 26 - .../vinyl-fs/lib/src/getContents/readDir.js | 8 - .../lib/src/getContents/streamFile.js | 13 - .../node_modules/vinyl-fs/lib/src/getStats.js | 19 - .../node_modules/vinyl-fs/lib/src/index.js | 62 - .../vinyl-fs/node_modules/.bin/mkdirp | 1 - .../vinyl-fs/node_modules/.bin/strip-bom | 1 - .../node_modules/glob-stream/.npmignore | 6 - .../node_modules/glob-stream/.travis.yml | 6 - .../vinyl-fs/node_modules/glob-stream/LICENSE | 20 - .../node_modules/glob-stream/README.md | 67 - .../node_modules/glob-stream/index.js | 119 - .../glob-stream/node_modules/glob/.npmignore | 3 - .../glob-stream/node_modules/glob/.travis.yml | 4 - .../glob-stream/node_modules/glob/LICENSE | 15 - .../glob-stream/node_modules/glob/README.md | 241 - .../node_modules/glob/examples/g.js | 9 - .../node_modules/glob/examples/usr-local.js | 9 - .../glob-stream/node_modules/glob/glob.js | 746 - .../glob/node_modules/inherits/LICENSE | 16 - .../glob/node_modules/inherits/README.md | 42 - .../glob/node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../glob/node_modules/inherits/package.json | 51 - .../glob/node_modules/inherits/test.js | 25 - .../glob/node_modules/once/LICENSE | 27 - .../glob/node_modules/once/README.md | 51 - .../once/node_modules/wrappy/LICENSE | 15 - .../once/node_modules/wrappy/README.md | 36 - .../once/node_modules/wrappy/package.json | 52 - .../once/node_modules/wrappy/test/basic.js | 51 - .../once/node_modules/wrappy/wrappy.js | 33 - .../glob/node_modules/once/once.js | 21 - .../glob/node_modules/once/package.json | 60 - .../glob/node_modules/once/test/once.js | 23 - .../node_modules/glob/oh-my-glob.gif | Bin 510360 -> 0 bytes .../node_modules/glob/package.json | 61 - .../node_modules/glob/test/00-setup.js | 176 - .../node_modules/glob/test/bash-comparison.js | 63 - .../node_modules/glob/test/bash-results.json | 356 - .../node_modules/glob/test/cwd-test.js | 55 - .../node_modules/glob/test/empty-set.js | 20 - .../node_modules/glob/test/error-callback.js | 21 - .../node_modules/glob/test/globstar-match.js | 19 - .../node_modules/glob/test/mark.js | 118 - .../node_modules/glob/test/negation-test.js | 16 - .../glob/test/new-glob-optional-options.js | 10 - .../node_modules/glob/test/nocase-nomagic.js | 125 - .../node_modules/glob/test/pause-resume.js | 73 - .../node_modules/glob/test/readme-issue.js | 36 - .../node_modules/glob/test/root-nomount.js | 39 - .../node_modules/glob/test/root.js | 46 - .../node_modules/glob/test/stat.js | 32 - .../node_modules/glob/test/zz-cleanup.js | 11 - .../node_modules/glob2base/.editorconfig | 10 - .../node_modules/glob2base/.jshintrc | 19 - .../node_modules/glob2base/.npmignore | 9 - .../node_modules/glob2base/.travis.yml | 6 - .../node_modules/glob2base/LICENSE | 20 - .../node_modules/glob2base/README.md | 51 - .../node_modules/glob2base/index.js | 60 - .../node_modules/glob2base/package.json | 68 - .../node_modules/glob2base/test/main.js | 53 - .../node_modules/minimatch/.npmignore | 1 - .../node_modules/minimatch/.travis.yml | 4 - .../node_modules/minimatch/LICENSE | 23 - .../node_modules/minimatch/README.md | 218 - .../node_modules/minimatch/minimatch.js | 1073 - .../node_modules/lru-cache/.npmignore | 1 - .../node_modules/lru-cache/CONTRIBUTORS | 14 - .../minimatch/node_modules/lru-cache/LICENSE | 23 - .../node_modules/lru-cache/README.md | 97 - .../node_modules/lru-cache/lib/lru-cache.js | 252 - .../node_modules/lru-cache/package.json | 50 - .../node_modules/lru-cache/test/basic.js | 369 - .../node_modules/lru-cache/test/foreach.js | 52 - .../lru-cache/test/memory-leak.js | 50 - .../minimatch/node_modules/sigmund/LICENSE | 27 - .../minimatch/node_modules/sigmund/README.md | 53 - .../minimatch/node_modules/sigmund/bench.js | 283 - .../node_modules/sigmund/package.json | 58 - .../minimatch/node_modules/sigmund/sigmund.js | 39 - .../node_modules/sigmund/test/basic.js | 24 - .../node_modules/minimatch/package.json | 58 - .../node_modules/minimatch/test/basic.js | 399 - .../minimatch/test/brace-expand.js | 40 - .../node_modules/minimatch/test/caching.js | 14 - .../node_modules/minimatch/test/defaults.js | 274 - .../test/extglob-ending-with-state-char.js | 8 - .../ordered-read-streams/.npmignore | 16 - .../ordered-read-streams/.travis.yml | 4 - .../node_modules/ordered-read-streams/LICENSE | 20 - .../ordered-read-streams/README.md | 65 - .../ordered-read-streams/index.js | 71 - .../ordered-read-streams/package.json | 50 - .../ordered-read-streams/test/main.js | 160 - .../node_modules/unique-stream/.npmignore | 3 - .../node_modules/unique-stream/.travis.yml | 3 - .../node_modules/unique-stream/LICENSE | 20 - .../node_modules/unique-stream/README.md | 89 - .../node_modules/unique-stream/index.js | 54 - .../node_modules/unique-stream/package.json | 55 - .../node_modules/unique-stream/test/index.js | 109 - .../node_modules/glob-stream/package.json | 71 - .../glob-stream/test/fixtures/.swag | 1 - .../glob-stream/test/fixtures/stuff/run.dmc | 0 .../glob-stream/test/fixtures/stuff/test.dmc | 0 .../glob-stream/test/fixtures/test.coffee | 1 - .../hey/isaidhey/whatsgoingon/test.txt | 1 - .../test/fixtures/whatsgoingon/test.js | 1 - .../node_modules/glob-stream/test/main.js | 425 - .../node_modules/glob-watcher/.npmignore | 6 - .../node_modules/glob-watcher/.travis.yml | 6 - .../node_modules/glob-watcher/LICENSE | 20 - .../node_modules/glob-watcher/README.md | 53 - .../node_modules/glob-watcher/index.js | 39 - .../node_modules/gaze/LICENSE-MIT | 22 - .../glob-watcher/node_modules/gaze/README.md | 180 - .../node_modules/gaze/lib/gaze.js | 439 - .../node_modules/gaze/lib/helper.js | 67 - .../gaze/node_modules/globule/.jshintrc | 15 - .../gaze/node_modules/globule/.npmignore | 1 - .../gaze/node_modules/globule/.travis.yml | 6 - .../gaze/node_modules/globule/Gruntfile.js | 48 - .../gaze/node_modules/globule/LICENSE-MIT | 22 - .../gaze/node_modules/globule/README.md | 117 - .../gaze/node_modules/globule/lib/globule.js | 172 - .../globule/node_modules/glob/.npmignore | 2 - .../globule/node_modules/glob/.travis.yml | 3 - .../globule/node_modules/glob/LICENSE | 27 - .../globule/node_modules/glob/README.md | 233 - .../globule/node_modules/glob/examples/g.js | 9 - .../node_modules/glob/examples/usr-local.js | 9 - .../globule/node_modules/glob/glob.js | 643 - .../glob/node_modules/graceful-fs/.npmignore | 1 - .../glob/node_modules/graceful-fs/LICENSE | 27 - .../glob/node_modules/graceful-fs/README.md | 33 - .../node_modules/graceful-fs/graceful-fs.js | 442 - .../node_modules/graceful-fs/package.json | 65 - .../node_modules/graceful-fs/test/open.js | 46 - .../node_modules/graceful-fs/test/ulimit.js | 158 - .../glob/node_modules/inherits/README.md | 51 - .../glob/node_modules/inherits/inherits.js | 29 - .../glob/node_modules/inherits/package.json | 46 - .../globule/node_modules/glob/package.json | 57 - .../node_modules/glob/test/00-setup.js | 176 - .../node_modules/glob/test/bash-comparison.js | 63 - .../node_modules/glob/test/bash-results.json | 348 - .../node_modules/glob/test/cwd-test.js | 55 - .../globule/node_modules/glob/test/mark.js | 74 - .../node_modules/glob/test/nocase-nomagic.js | 113 - .../node_modules/glob/test/pause-resume.js | 73 - .../node_modules/glob/test/root-nomount.js | 39 - .../globule/node_modules/glob/test/root.js | 46 - .../node_modules/glob/test/zz-cleanup.js | 11 - .../globule/node_modules/lodash/README.md | 164 - .../node_modules/lodash/dist/lodash.compat.js | 5152 ---- .../lodash/dist/lodash.compat.min.js | 42 - .../node_modules/lodash/dist/lodash.js | 4983 ---- .../node_modules/lodash/dist/lodash.min.js | 40 - .../lodash/dist/lodash.underscore.js | 4307 ---- .../lodash/dist/lodash.underscore.min.js | 34 - .../globule/node_modules/lodash/package.json | 79 - .../globule/node_modules/minimatch/.npmignore | 1 - .../globule/node_modules/minimatch/LICENSE | 23 - .../globule/node_modules/minimatch/README.md | 218 - .../node_modules/minimatch/minimatch.js | 1055 - .../node_modules/lru-cache/.npmignore | 1 - .../node_modules/lru-cache/CONTRIBUTORS | 14 - .../minimatch/node_modules/lru-cache/LICENSE | 23 - .../node_modules/lru-cache/README.md | 97 - .../node_modules/lru-cache/lib/lru-cache.js | 252 - .../node_modules/lru-cache/package.json | 50 - .../node_modules/lru-cache/test/basic.js | 369 - .../node_modules/lru-cache/test/foreach.js | 52 - .../lru-cache/test/memory-leak.js | 50 - .../minimatch/node_modules/sigmund/LICENSE | 27 - .../minimatch/node_modules/sigmund/README.md | 53 - .../minimatch/node_modules/sigmund/bench.js | 283 - .../node_modules/sigmund/package.json | 58 - .../minimatch/node_modules/sigmund/sigmund.js | 39 - .../node_modules/sigmund/test/basic.js | 24 - .../node_modules/minimatch/package.json | 57 - .../node_modules/minimatch/test/basic.js | 399 - .../minimatch/test/brace-expand.js | 33 - .../node_modules/minimatch/test/caching.js | 14 - .../node_modules/minimatch/test/defaults.js | 274 - .../test/extglob-ending-with-state-char.js | 8 - .../gaze/node_modules/globule/package.json | 74 - .../globule/test/fixtures/expand/README.md | 0 .../globule/test/fixtures/expand/css/baz.css | 0 .../globule/test/fixtures/expand/css/qux.css | 0 .../test/fixtures/expand/deep/deep.txt | 0 .../fixtures/expand/deep/deeper/deeper.txt | 0 .../expand/deep/deeper/deepest/deepest.txt | 0 .../globule/test/fixtures/expand/js/bar.js | 0 .../globule/test/fixtures/expand/js/foo.js | 0 .../node_modules/globule/test/globule_test.js | 486 - .../node_modules/gaze/package.json | 71 - .../node_modules/glob-watcher/package.json | 66 - .../glob-watcher/test/fixtures/test.coffee | 1 - .../node_modules/glob-watcher/test/main.js | 87 - .../node_modules/graceful-fs/.npmignore | 1 - .../vinyl-fs/node_modules/graceful-fs/LICENSE | 27 - .../node_modules/graceful-fs/README.md | 36 - .../vinyl-fs/node_modules/graceful-fs/fs.js | 11 - .../node_modules/graceful-fs/graceful-fs.js | 158 - .../node_modules/graceful-fs/package.json | 71 - .../node_modules/graceful-fs/polyfills.js | 255 - .../node_modules/graceful-fs/test/max-open.js | 69 - .../node_modules/graceful-fs/test/open.js | 39 - .../graceful-fs/test/readdir-sort.js | 20 - .../graceful-fs/test/write-then-read.js | 45 - .../vinyl-fs/node_modules/lodash/LICENSE.txt | 22 - .../vinyl-fs/node_modules/lodash/README.md | 163 - .../node_modules/lodash/dist/lodash.compat.js | 7157 ------ .../lodash/dist/lodash.compat.min.js | 61 - .../node_modules/lodash/dist/lodash.js | 6785 ------ .../node_modules/lodash/dist/lodash.min.js | 56 - .../lodash/dist/lodash.underscore.js | 4979 ---- .../lodash/dist/lodash.underscore.min.js | 39 - .../vinyl-fs/node_modules/lodash/lodash.js | 7179 ------ .../vinyl-fs/node_modules/lodash/package.json | 132 - .../vinyl-fs/node_modules/mkdirp/.npmignore | 2 - .../vinyl-fs/node_modules/mkdirp/.travis.yml | 5 - .../vinyl-fs/node_modules/mkdirp/LICENSE | 21 - .../vinyl-fs/node_modules/mkdirp/bin/cmd.js | 33 - .../node_modules/mkdirp/bin/usage.txt | 12 - .../node_modules/mkdirp/examples/pow.js | 6 - .../vinyl-fs/node_modules/mkdirp/index.js | 97 - .../mkdirp/node_modules/minimist/.travis.yml | 4 - .../mkdirp/node_modules/minimist/LICENSE | 18 - .../node_modules/minimist/example/parse.js | 2 - .../mkdirp/node_modules/minimist/index.js | 187 - .../mkdirp/node_modules/minimist/package.json | 67 - .../node_modules/minimist/readme.markdown | 73 - .../mkdirp/node_modules/minimist/test/dash.js | 24 - .../minimist/test/default_bool.js | 20 - .../node_modules/minimist/test/dotted.js | 16 - .../mkdirp/node_modules/minimist/test/long.js | 31 - .../node_modules/minimist/test/parse.js | 318 - .../minimist/test/parse_modified.js | 9 - .../node_modules/minimist/test/short.js | 67 - .../node_modules/minimist/test/whitespace.js | 8 - .../vinyl-fs/node_modules/mkdirp/package.json | 58 - .../node_modules/mkdirp/readme.markdown | 100 - .../node_modules/mkdirp/test/chmod.js | 38 - .../node_modules/mkdirp/test/clobber.js | 37 - .../node_modules/mkdirp/test/mkdirp.js | 26 - .../node_modules/mkdirp/test/opts_fs.js | 27 - .../node_modules/mkdirp/test/opts_fs_sync.js | 25 - .../vinyl-fs/node_modules/mkdirp/test/perm.js | 30 - .../node_modules/mkdirp/test/perm_sync.js | 34 - .../vinyl-fs/node_modules/mkdirp/test/race.js | 40 - .../vinyl-fs/node_modules/mkdirp/test/rel.js | 30 - .../node_modules/mkdirp/test/return.js | 25 - .../node_modules/mkdirp/test/return_sync.js | 24 - .../vinyl-fs/node_modules/mkdirp/test/root.js | 18 - .../vinyl-fs/node_modules/mkdirp/test/sync.js | 30 - .../node_modules/mkdirp/test/umask.js | 26 - .../node_modules/mkdirp/test/umask_sync.js | 30 - .../vinyl-fs/node_modules/strip-bom/cli.js | 42 - .../vinyl-fs/node_modules/strip-bom/index.js | 24 - .../node_modules/first-chunk-stream/index.js | 93 - .../first-chunk-stream/package.json | 65 - .../node_modules/first-chunk-stream/readme.md | 62 - .../strip-bom/node_modules/is-utf8/README.md | 12 - .../strip-bom/node_modules/is-utf8/ansi.txt | 7 - .../strip-bom/node_modules/is-utf8/is-utf8.js | 76 - .../node_modules/is-utf8/package.json | 46 - .../strip-bom/node_modules/is-utf8/test.js | 7 - .../strip-bom/node_modules/is-utf8/utf8.txt | 7 - .../node_modules/strip-bom/package.json | 80 - .../vinyl-fs/node_modules/strip-bom/readme.md | 59 - .../vinyl-fs/node_modules/through2/.npmignore | 3 - .../vinyl-fs/node_modules/through2/LICENSE | 39 - .../vinyl-fs/node_modules/through2/README.md | 149 - .../node_modules/readable-stream/.npmignore | 5 - .../node_modules/readable-stream/LICENSE | 27 - .../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/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 | 54 - .../node_modules/core-util-is/util.js | 106 - .../node_modules/inherits/LICENSE | 16 - .../node_modules/inherits/README.md | 42 - .../node_modules/inherits/inherits.js | 1 - .../node_modules/inherits/inherits_browser.js | 23 - .../node_modules/inherits/package.json | 51 - .../node_modules/inherits/test.js | 25 - .../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 | 54 - .../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/readable-stream/package.json | 70 - .../readable-stream/passthrough.js | 1 - .../node_modules/readable-stream/readable.js | 7 - .../node_modules/readable-stream/transform.js | 1 - .../node_modules/readable-stream/writable.js | 1 - .../through2/node_modules/xtend/.jshintrc | 30 - .../through2/node_modules/xtend/.npmignore | 1 - .../through2/node_modules/xtend/LICENCE | 19 - .../through2/node_modules/xtend/Makefile | 4 - .../through2/node_modules/xtend/README.md | 32 - .../through2/node_modules/xtend/immutable.js | 17 - .../through2/node_modules/xtend/mutable.js | 15 - .../through2/node_modules/xtend/package.json | 88 - .../through2/node_modules/xtend/test.js | 63 - .../node_modules/through2/package.json | 65 - .../node_modules/through2/through2.js | 96 - .../vinyl-fs/node_modules/vinyl/.jshintignore | 2 - .../vinyl-fs/node_modules/vinyl/.jshintrc | 36 - .../vinyl-fs/node_modules/vinyl/.npmignore | 6 - .../vinyl-fs/node_modules/vinyl/.travis.yml | 5 - .../vinyl-fs/node_modules/vinyl/LICENSE | 20 - .../vinyl-fs/node_modules/vinyl/README.md | 127 - .../node_modules/vinyl/coverage/coverage.json | 1 - .../vinyl/coverage/lcov-report/index.html | 363 - .../vinyl/coverage/lcov-report/prettify.css | 1 - .../vinyl/coverage/lcov-report/prettify.js | 1 - .../coverage/lcov-report/vinyl/index.html | 350 - .../coverage/lcov-report/vinyl/index.js.html | 847 - .../lcov-report/vinyl/lib/cloneBuffer.js.html | 343 - .../coverage/lcov-report/vinyl/lib/index.html | 402 - .../vinyl/lib/inspectStream.js.html | 355 - .../lcov-report/vinyl/lib/isBuffer.js.html | 340 - .../lcov-report/vinyl/lib/isNull.js.html | 331 - .../lcov-report/vinyl/lib/isStream.js.html | 334 - .../node_modules/vinyl/coverage/lcov.info | 280 - .../vinyl-fs/node_modules/vinyl/index.js | 175 - .../node_modules/vinyl/lib/cloneBuffer.js | 7 - .../node_modules/vinyl/lib/inspectStream.js | 11 - .../node_modules/vinyl/lib/isBuffer.js | 7 - .../vinyl-fs/node_modules/vinyl/lib/isNull.js | 3 - .../node_modules/vinyl/lib/isStream.js | 5 - .../vinyl/node_modules/clone-stats/LICENSE.md | 21 - .../vinyl/node_modules/clone-stats/README.md | 17 - .../vinyl/node_modules/clone-stats/index.js | 13 - .../node_modules/clone-stats/package.json | 57 - .../vinyl/node_modules/clone-stats/test.js | 36 - .../vinyl-fs/node_modules/vinyl/package.json | 70 - .../vinyl-fs/node_modules/vinyl/perf/clone.js | 59 - .../vinyl-fs/node_modules/vinyl/test/File.js | 753 - .../node_modules/vinyl/test/cloneBuffer.js | 27 - .../node_modules/vinyl/test/inspectStream.js | 53 - .../node_modules/vinyl/test/isBuffer.js | 29 - .../node_modules/vinyl/test/isNull.js | 22 - .../node_modules/vinyl/test/isStream.js | 29 - .../gulp/node_modules/vinyl-fs/package.json | 77 - .../gulp/node_modules/vinyl-fs/test/dest.js | 631 - .../vinyl-fs/test/fixtures/bom-utf16be.txt | Bin 244 -> 0 bytes .../vinyl-fs/test/fixtures/bom-utf16le.txt | Bin 244 -> 0 bytes .../vinyl-fs/test/fixtures/bom-utf8.txt | 1 - .../vinyl-fs/test/fixtures/test.coffee | 1 - .../vinyl-fs/test/fixtures/wow/suchempty | 1 - .../gulp/node_modules/vinyl-fs/test/spy.js | 27 - .../gulp/node_modules/vinyl-fs/test/src.js | 247 - spec/fixture/node_modules/gulp/package.json | 107 - spec/fixture/package.json.install | 13 - 1620 files changed, 379331 deletions(-) delete mode 120000 spec/fixture/node_modules/.bin/grunt delete mode 120000 spec/fixture/node_modules/.bin/gulp delete mode 100644 spec/fixture/node_modules/grunt-cli/.npmignore delete mode 100644 spec/fixture/node_modules/grunt-cli/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt-cli/AUTHORS delete mode 100644 spec/fixture/node_modules/grunt-cli/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt-cli/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt-cli/README.md delete mode 100755 spec/fixture/node_modules/grunt-cli/bin/grunt delete mode 100755 spec/fixture/node_modules/grunt-cli/completion/bash delete mode 100755 spec/fixture/node_modules/grunt-cli/completion/zsh delete mode 100644 spec/fixture/node_modules/grunt-cli/lib/cli.js delete mode 100644 spec/fixture/node_modules/grunt-cli/lib/completion.js delete mode 100644 spec/fixture/node_modules/grunt-cli/lib/info.js delete mode 120000 spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.npmignore delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/test/findup-sync_test.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/test/fixtures/a.txt delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/test/fixtures/a/b/bar.txt delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/test/fixtures/a/foo.txt delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/test/fixtures/aaa.txt delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/.gitignore delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/README.md delete mode 100755 spec/fixture/node_modules/grunt-cli/node_modules/nopt/bin/nopt.js delete mode 100755 spec/fixture/node_modules/grunt-cli/node_modules/nopt/examples/my-program.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/lib/nopt.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/node_modules/abbrev/CONTRIBUTING.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/node_modules/abbrev/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/node_modules/abbrev/README.md delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/node_modules/abbrev/abbrev.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/node_modules/abbrev/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/node_modules/abbrev/test.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/nopt/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/LICENSE delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/example/async.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/example/sync.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/index.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/lib/async.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/lib/core.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/lib/core.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/lib/sync.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/readme.markdown delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/core.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/filter.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/filter_sync.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/mock.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/mock_sync.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/bar/node_modules/foo/index.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/baz/doom.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/baz/package.json delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/baz/quux.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/biz/node_modules/grux/index.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/biz/node_modules/tiv/index.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/cup.coffee delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/foo.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/mug.coffee delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/mug.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/other_path/lib/other-lib.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver/other_path/root.js delete mode 100644 spec/fixture/node_modules/grunt-cli/node_modules/resolve/test/resolver_sync.js delete mode 100644 spec/fixture/node_modules/grunt-cli/package.json delete mode 100644 spec/fixture/node_modules/grunt/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/CONTRIBUTING.md delete mode 100644 spec/fixture/node_modules/grunt/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/README.md delete mode 100644 spec/fixture/node_modules/grunt/appveyor.yml delete mode 100644 spec/fixture/node_modules/grunt/internal-tasks/bump.js delete mode 100644 spec/fixture/node_modules/grunt/internal-tasks/subgrunt.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/cli.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/config.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/event.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/fail.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/file.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/help.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/option.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/task.js delete mode 100644 spec/fixture/node_modules/grunt/lib/grunt/template.js delete mode 100644 spec/fixture/node_modules/grunt/lib/util/task.js delete mode 120000 spec/fixture/node_modules/grunt/node_modules/.bin/cake delete mode 120000 spec/fixture/node_modules/grunt/node_modules/.bin/coffee delete mode 120000 spec/fixture/node_modules/grunt/node_modules/.bin/js-yaml delete mode 120000 spec/fixture/node_modules/grunt/node_modules/.bin/nopt delete mode 120000 spec/fixture/node_modules/grunt/node_modules/.bin/rimraf delete mode 120000 spec/fixture/node_modules/grunt/node_modules/.bin/which delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/.gitmodules delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/Makefile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/lib/async.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/async/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/README delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile delete mode 100755 spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake delete mode 100755 spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/colors.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/example.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/example.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/dateformat/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh delete mode 100644 spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/eventemitter2/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt delete mode 100755 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/test/findup-sync_test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/test/fixtures/a.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/test/fixtures/a/b/bar.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/test/fixtures/a/foo.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/findup-sync/test/fixtures/aaa.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/.jshintrc delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/lib/getobject.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/getobject/test/namespace_test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/examples/g.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/examples/usr-local.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/glob.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/graceful-fs.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/test/open.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/graceful-fs/test/ulimit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/00-setup.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/bash-comparison.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/bash-results.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/cwd-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/mark.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/nocase-nomagic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/pause-resume.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/root-nomount.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/root.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/glob/test/zz-cleanup.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/.jshintrc delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/examples.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/LICENSE.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Gemfile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Gemfile.lock delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/README.markdown delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings_standalone.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/vendor/jquery.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/vendor/jslitmus.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/vendor/qunit.css delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/vendor/qunit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/test/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/.jshintrc delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/Gruntfile.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv-child.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-execArgv.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/Gruntfile-print-text.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.cmd delete mode 100755 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/exec.sh delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn-multibyte.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/fixtures/spawn.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/grunt-legacy-util/test/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/child.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/grunt.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/lib/hooker.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/parent.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/hooker/test/hooker_test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md~ delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/big5.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/gbk.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/singlebyte.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/big5.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/gbk.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-big5-table.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-singlebyte.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5File.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/cyrillic-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbk-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbkFile.txt delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/greek-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/main-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/performance.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/turkish-test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/HISTORY.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/README.md delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/bin/js-yaml.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.yaml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.yaml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/common.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/dumper.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/exception.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/loader.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/mark.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/require.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/default.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/minimal.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/safe.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/binary.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/bool.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/float.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/int.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/function.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/map.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/merge.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/null.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/omap.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/pairs.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/seq.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/set.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/str.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/timestamp.js delete mode 120000 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esparse delete mode 120000 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esvalidate delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/HISTORY.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/README.md delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/arguments.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/choice.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/constants.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/help.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/nargs.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/parents.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/prefix_chars.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sub_commands.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sum.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/testformatters.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append/constant.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/count.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/help.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/constant.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/false.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/true.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/subparsers.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/version.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action_container.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argparse.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/error.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/exclusive.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/group.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument_parser.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/const.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/added_formatters.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/formatter.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/namespace.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile.lock delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/README.markdown delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Rakefile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/component.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/dist/underscore.string.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/libpeerconnection.log delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/run-qunit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/speed.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/strings.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/strings_standalone.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_standalone.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/arrays.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/chaining.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/collections.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/functions.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/index.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/objects.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/speed.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/utility.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/vendor/jquery.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/vendor/jslitmus.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/vendor/qunit.css delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/vendor/qunit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/CNAME delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/CONTRIBUTING.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/favicon.ico delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/index.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/index.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore-min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/README.md delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esparse.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esvalidate.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/esprima.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/compat.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/reflect.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/run.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/runner.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/js-yaml/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/lodash/lodash.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/lodash/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/lodash/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/minimatch.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/.npmignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/test/foreach.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/sigmund/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/sigmund/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/sigmund/bench.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/sigmund/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/sigmund/sigmund.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/node_modules/sigmund/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/test/basic.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/test/brace-expand.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/test/caching.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/test/defaults.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/minimatch/test/extglob-ending-with-state-char.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/.gitignore delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/README.md delete mode 100755 spec/fixture/node_modules/grunt/node_modules/nopt/bin/nopt.js delete mode 100755 spec/fixture/node_modules/grunt/node_modules/nopt/examples/my-program.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/lib/nopt.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/node_modules/abbrev/CONTRIBUTING.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/node_modules/abbrev/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/node_modules/abbrev/README.md delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/node_modules/abbrev/abbrev.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/node_modules/abbrev/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/node_modules/abbrev/test.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/nopt/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/AUTHORS delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/README.md delete mode 100755 spec/fixture/node_modules/grunt/node_modules/rimraf/bin.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/rimraf.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/test/run.sh delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/test/setup.sh delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/test/test-async.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/rimraf/test/test-sync.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/.travis.yml delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/Gemfile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/Gemfile.lock delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/README.markdown delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/Rakefile delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/dist/underscore.string.min.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/lib/underscore.string.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/run-qunit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/speed.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/strings.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/strings_standalone.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_standalone.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/arrays.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/chaining.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/collections.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/functions.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/objects.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/speed.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp_tests.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/test.html delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/utility.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/vendor/jquery.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/vendor/jslitmus.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/vendor/qunit.css delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/vendor/qunit.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/underscore.string/test/underscore.js delete mode 100644 spec/fixture/node_modules/grunt/node_modules/which/LICENSE delete mode 100644 spec/fixture/node_modules/grunt/node_modules/which/README.md delete mode 100755 spec/fixture/node_modules/grunt/node_modules/which/bin/which delete mode 100644 spec/fixture/node_modules/grunt/node_modules/which/package.json delete mode 100644 spec/fixture/node_modules/grunt/node_modules/which/which.js delete mode 100644 spec/fixture/node_modules/grunt/package.json delete mode 100644 spec/fixture/node_modules/gulp/README.md delete mode 100755 spec/fixture/node_modules/gulp/bin/gulp.js delete mode 100644 spec/fixture/node_modules/gulp/completion/README.md delete mode 100644 spec/fixture/node_modules/gulp/completion/bash delete mode 100644 spec/fixture/node_modules/gulp/completion/fish delete mode 100644 spec/fixture/node_modules/gulp/completion/powershell delete mode 100644 spec/fixture/node_modules/gulp/completion/zsh delete mode 100644 spec/fixture/node_modules/gulp/index.js delete mode 100644 spec/fixture/node_modules/gulp/lib/completion.js delete mode 100644 spec/fixture/node_modules/gulp/lib/taskTree.js delete mode 120000 spec/fixture/node_modules/gulp/node_modules/.bin/semver delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/README.markdown delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/examples/beep.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/examples/multi_line.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/test/beep.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/test/multi_line.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/archy/test/non_unicode.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/index.js delete mode 120000 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/.bin/has-ansi delete mode 120000 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/.bin/strip-ansi delete mode 120000 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/.bin/supports-color delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/ansi-styles/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/ansi-styles/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/ansi-styles/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/escape-string-regexp/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/escape-string-regexp/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/escape-string-regexp/readme.md delete mode 100755 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/cli.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/node_modules/ansi-regex/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/node_modules/ansi-regex/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/node_modules/ansi-regex/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/has-ansi/readme.md delete mode 100755 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/cli.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/node_modules/ansi-regex/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/node_modules/ansi-regex/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/node_modules/ansi-regex/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/strip-ansi/readme.md delete mode 100755 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/supports-color/cli.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/supports-color/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/supports-color/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/node_modules/supports-color/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/chalk/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/.travis.yml delete mode 100755 spec/fixture/node_modules/gulp/node_modules/deprecated/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/test/field.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/deprecated/test/method.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/.travis.yml delete mode 100755 spec/fixture/node_modules/gulp/node_modules/gulp-util/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/File.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/PluginError.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/beep.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/buffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/colors.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/combine.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/date.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/env.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/isBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/isNull.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/isStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/linefeed.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/log.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/noop.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/replaceExtension.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/lib/template.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/Readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/lib/dateformat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/test/test_dayofweek.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/test/test_weekofyear.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/dateformat/test/test_weekofyear.sh delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash._reinterpolate/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash._reinterpolate/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash._reinterpolate/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash._reinterpolate/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash._escapestringchar/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash._escapestringchar/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash._escapestringchar/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash._escapestringchar/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/node_modules/lodash._objecttypes/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/node_modules/lodash._objecttypes/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/node_modules/lodash._objecttypes/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/node_modules/lodash._objecttypes/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.defaults/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/node_modules/lodash._htmlescapes/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/node_modules/lodash._htmlescapes/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/node_modules/lodash._htmlescapes/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/node_modules/lodash._htmlescapes/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/node_modules/lodash._htmlescapes/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/node_modules/lodash._htmlescapes/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/node_modules/lodash._htmlescapes/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/node_modules/lodash._htmlescapes/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._reunescapedhtml/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.escape/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._isnative/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._isnative/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._isnative/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._isnative/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/node_modules/lodash._objecttypes/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/node_modules/lodash._objecttypes/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/node_modules/lodash._objecttypes/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/node_modules/lodash._objecttypes/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash._shimkeys/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/node_modules/lodash._objecttypes/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/node_modules/lodash._objecttypes/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/node_modules/lodash._objecttypes/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/node_modules/lodash._objecttypes/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/node_modules/lodash.isobject/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.keys/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.templatesettings/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.templatesettings/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.templatesettings/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.templatesettings/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.values/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.values/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.values/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/node_modules/lodash.values/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash.template/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/History.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/Makefile delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/Readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/LICENSE.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/README.md delete mode 100755 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/example.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/duplex.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/float.patch delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/lib/_stream_duplex.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/lib/_stream_passthrough.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/lib/_stream_readable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/lib/_stream_transform.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/lib/_stream_writable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/core-util-is/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/core-util-is/float.patch delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/core-util-is/lib/util.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/core-util-is/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/core-util-is/util.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/isarray/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/isarray/build/build.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/isarray/component.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/isarray/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/isarray/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/string_decoder/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/string_decoder/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/string_decoder/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/string_decoder/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/node_modules/string_decoder/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/passthrough.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/readable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/transform.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/node_modules/readable-stream/writable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/node_modules/duplexer2/test/tests.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/multipipe/test/multipipe.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/duplex.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/float.patch delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/lib/util.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/util.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/isarray/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/isarray/build/build.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/isarray/component.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/isarray/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/isarray/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/passthrough.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/readable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/transform.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/readable-stream/writable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/LICENCE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/Makefile delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/immutable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/mutable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/node_modules/xtend/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/through2/through2.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/.jshintignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/coverage.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/index.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.css delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov.info delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/cloneBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/inspectStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isNull.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/LICENSE.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/perf/clone.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/File.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/cloneBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/inspectStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isNull.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/gulp-util/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/interpret/CHANGELOG delete mode 100644 spec/fixture/node_modules/gulp/node_modules/interpret/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/interpret/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/interpret/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/interpret/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/CHANGELOG delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/UPGRADING.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/appveyor.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.eps delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.png delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.svg delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.eps delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.png delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.svg delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/lib/build_config_name.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/lib/file_search.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_config.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_cwd.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/lib/parse_options.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/lib/silent_require.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/component.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/Gruntfile.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/lib/findup-sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/g.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/usr-local.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/00-setup.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-results.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/cwd-test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/globstar-match.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/mark.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/pause-resume.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/readme-issue.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root-nomount.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/stat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/test/findup-sync_test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/test/fixtures/a.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/test/fixtures/a/b/bar.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/test/fixtures/a/foo.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/test/fixtures/aaa.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/lib/reorder.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/lib/respawn.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/test/bin/exit_code.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/test/bin/respawner.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/test/bin/signal.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/flagged-respawn/test/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/example/async.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/example/sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/lib/async.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/lib/caller.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/lib/core.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/lib/core.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/lib/node-modules-paths.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/lib/sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/readme.markdown delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/core.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/dotdot.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/dotdot/abc/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/dotdot/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/faulty_basedir.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/filter.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/filter_sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/mock.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/mock_sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/module_dir.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/module_dir/xmodules/aaa/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/module_dir/ymodules/aaa/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/module_dir/zmodules/bbb/main.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/module_dir/zmodules/bbb/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/node_path.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/node_path/x/aaa/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/node_path/x/ccc/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/node_path/y/bbb/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/node_path/y/ccc/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/nonstring.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/bar/node_modules/foo/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/baz/doom.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/baz/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/baz/quux.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/biz/node_modules/garply/lib/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/biz/node_modules/garply/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/biz/node_modules/grux/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/biz/node_modules/tiv/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/cup.coffee delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/foo.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/incorrect_main/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/incorrect_main/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/mug.coffee delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/mug.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/other_path/lib/other-lib.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/other_path/root.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/punycode/node_modules/punycode/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/quux/foo/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/without_basedir/main.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver/without_basedir/node_modules/mymodule.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/resolve/test/resolver_sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/liftoff/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/example/parse.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/readme.markdown delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/all_bool.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/bool.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/dash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/default_bool.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/dotted.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/long.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/num.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/parse.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/parse_modified.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/short.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/stop_early.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/unknown.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/minimist/test/whitespace.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/lib/runTask.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/node_modules/wrappy/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/node_modules/wrappy/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/node_modules/wrappy/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/node_modules/wrappy/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/node_modules/wrappy/wrappy.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/once.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/test/once.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/sequencify/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/sequencify/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/sequencify/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/sequencify/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/sequencify/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/sequencify/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/stream-consume/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/stream-consume/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/stream-consume/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/stream-consume/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/node_modules/stream-consume/test/tests.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/orchestrator/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/pretty-hrtime/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/pretty-hrtime/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/pretty-hrtime/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/pretty-hrtime/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/pretty-hrtime/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/Makefile delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/README.md delete mode 100755 spec/fixture/node_modules/gulp/node_modules/semver/bin/semver delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/foot.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/head.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/semver.browser.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/semver.browser.js.gz delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/semver.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/semver.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/semver.min.js.gz delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/test/amd.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/test/clean.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/test/gtr.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/test/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/test/ltr.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/semver/test/no-module.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/tildify/index.js delete mode 120000 spec/fixture/node_modules/gulp/node_modules/tildify/node_modules/.bin/user-home delete mode 100755 spec/fixture/node_modules/gulp/node_modules/tildify/node_modules/user-home/cli.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/tildify/node_modules/user-home/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/tildify/node_modules/user-home/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/tildify/node_modules/user-home/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/tildify/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/tildify/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/3.14.5.9.flags.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/fetch.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/v8flags/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/.editorconfig delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/.travis.yml delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/dest/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/dest/writeContents/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/dest/writeContents/writeBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/dest/writeContents/writeDir.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/dest/writeContents/writeStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/src/getContents/bufferFile.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/src/getContents/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/src/getContents/readDir.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/src/getContents/streamFile.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/src/getStats.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/lib/src/index.js delete mode 120000 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/.bin/mkdirp delete mode 120000 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/.bin/strip-bom delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/.travis.yml delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/examples/g.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/examples/usr-local.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/glob.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/node_modules/wrappy/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/node_modules/wrappy/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/node_modules/wrappy/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/node_modules/wrappy/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/node_modules/wrappy/wrappy.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/once.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/node_modules/once/test/once.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/oh-my-glob.gif delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/00-setup.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/bash-comparison.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/bash-results.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/cwd-test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/empty-set.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/error-callback.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/globstar-match.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/mark.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/negation-test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/new-glob-optional-options.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/nocase-nomagic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/pause-resume.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/readme-issue.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/root-nomount.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/root.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/stat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob/test/zz-cleanup.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/.editorconfig delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/.travis.yml delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/glob2base/test/main.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/minimatch.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/test/foreach.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/sigmund/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/sigmund/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/sigmund/bench.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/sigmund/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/sigmund/sigmund.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/node_modules/sigmund/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/test/brace-expand.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/test/caching.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/test/defaults.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/minimatch/test/extglob-ending-with-state-char.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/ordered-read-streams/test/main.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/node_modules/unique-stream/test/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/fixtures/.swag delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/fixtures/stuff/run.dmc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/fixtures/stuff/test.dmc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/fixtures/test.coffee delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/fixtures/whatsgoingon/hey/isaidhey/whatsgoingon/test.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/fixtures/whatsgoingon/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-stream/test/main.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/.travis.yml delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/helper.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/Gruntfile.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/LICENSE-MIT delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/lib/globule.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/examples/g.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/examples/usr-local.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/glob.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/graceful-fs.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/test/open.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs/test/ulimit.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/00-setup.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/bash-comparison.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/bash-results.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/cwd-test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/mark.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/nocase-nomagic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/pause-resume.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/root-nomount.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/root.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/glob/test/zz-cleanup.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/minimatch.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/test/foreach.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/sigmund/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/sigmund/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/sigmund/bench.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/sigmund/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/sigmund/sigmund.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/node_modules/sigmund/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/test/basic.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/test/brace-expand.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/test/caching.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/test/defaults.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/minimatch/test/extglob-ending-with-state-char.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/css/baz.css delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/css/qux.css delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/deep/deep.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/deep/deeper/deeper.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/deep/deeper/deepest/deepest.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/js/bar.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/fixtures/expand/js/foo.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/test/globule_test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/test/fixtures/test.coffee delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/test/main.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/fs.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/graceful-fs.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/polyfills.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/test/max-open.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/test/open.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/test/readdir-sort.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/graceful-fs/test/write-then-read.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/LICENSE.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.compat.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.compat.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.underscore.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.underscore.min.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/lodash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/LICENSE delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/bin/cmd.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/bin/usage.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/examples/pow.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/example/parse.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/readme.markdown delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/dash.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/default_bool.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/dotted.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/long.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/parse.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/short.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/node_modules/minimist/test/whitespace.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/readme.markdown delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/chmod.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/clobber.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/mkdirp.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/opts_fs.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/opts_fs_sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/perm.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/perm_sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/race.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/rel.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/return.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/return_sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/root.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/sync.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/umask.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/mkdirp/test/umask_sync.js delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/cli.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/first-chunk-stream/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/first-chunk-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/first-chunk-stream/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/is-utf8/README.md delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/is-utf8/ansi.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/is-utf8/is-utf8.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/is-utf8/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/is-utf8/test.js delete mode 100755 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/node_modules/is-utf8/utf8.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/strip-bom/readme.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/duplex.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/float.patch delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/lib/util.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/core-util-is/util.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/inherits/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/inherits/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/inherits/inherits.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/inherits/inherits_browser.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/inherits/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/inherits/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/isarray/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/isarray/build/build.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/isarray/component.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/isarray/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/isarray/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/node_modules/string_decoder/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/passthrough.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/readable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/transform.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/writable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/LICENCE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/Makefile delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/immutable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/mutable.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/xtend/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/through2.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/.jshintignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/.jshintrc delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/.npmignore delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/.travis.yml delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/LICENSE delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/coverage.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/index.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.css delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov.info delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/cloneBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/inspectStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isNull.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/LICENSE.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/README.md delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/index.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/test.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/perf/clone.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/File.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/cloneBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/inspectStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isBuffer.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isNull.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isStream.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/package.json delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/dest.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf16be.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf16le.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf8.txt delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/test.coffee delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/wow/suchempty delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/spy.js delete mode 100644 spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/src.js delete mode 100644 spec/fixture/node_modules/gulp/package.json delete mode 100644 spec/fixture/package.json.install diff --git a/spec/fixture/node_modules/.bin/grunt b/spec/fixture/node_modules/.bin/grunt deleted file mode 120000 index 1ac2c4d3..00000000 --- a/spec/fixture/node_modules/.bin/grunt +++ /dev/null @@ -1 +0,0 @@ -../grunt-cli/bin/grunt \ No newline at end of file diff --git a/spec/fixture/node_modules/.bin/gulp b/spec/fixture/node_modules/.bin/gulp deleted file mode 120000 index 5de73328..00000000 --- a/spec/fixture/node_modules/.bin/gulp +++ /dev/null @@ -1 +0,0 @@ -../gulp/bin/gulp.js \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt-cli/.npmignore b/spec/fixture/node_modules/grunt-cli/.npmignore deleted file mode 100644 index b785247e..00000000 --- a/spec/fixture/node_modules/grunt-cli/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -npm-debug.log -tmp diff --git a/spec/fixture/node_modules/grunt-cli/.travis.yml b/spec/fixture/node_modules/grunt-cli/.travis.yml deleted file mode 100644 index a12e3f0f..00000000 --- a/spec/fixture/node_modules/grunt-cli/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt-cli/AUTHORS b/spec/fixture/node_modules/grunt-cli/AUTHORS deleted file mode 100644 index a9a36590..00000000 --- a/spec/fixture/node_modules/grunt-cli/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -Tyler Kellen (http://goingslowly.com) -Ben Alman (http://gruntjs.com) -Scott González (http://nemikor.com) -Forbes Lindesay (https://github.com/) diff --git a/spec/fixture/node_modules/grunt-cli/Gruntfile.js b/spec/fixture/node_modules/grunt-cli/Gruntfile.js deleted file mode 100644 index 02fc2ffc..00000000 --- a/spec/fixture/node_modules/grunt-cli/Gruntfile.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * grunt-cli - * http://gruntjs.com/ - * - * Copyright (c) 2012 Tyler Kellen, contributors - * Licensed under the MIT license. - * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT - */ - -'use strict'; - -module.exports = function(grunt) { - - // Project configuration. - grunt.initConfig({ - jshint: { - all: [ - 'Gruntfile.js', - 'lib/**/*.js', - 'bin/*', - ], - options: { - curly: true, - eqeqeq: true, - immed: true, - latedef: true, - newcap: true, - noarg: true, - sub: true, - undef: true, - unused: true, - boss: true, - eqnull: true, - node: true, - es5: true - } - }, - }); - - // These plugins provide necessary tasks. - grunt.loadNpmTasks('grunt-contrib-jshint'); - - // "npm test" runs these tasks - grunt.registerTask('test', ['jshint']); - - // Default task. - grunt.registerTask('default', ['test']); - -}; diff --git a/spec/fixture/node_modules/grunt-cli/LICENSE-MIT b/spec/fixture/node_modules/grunt-cli/LICENSE-MIT deleted file mode 100644 index 91df6e9b..00000000 --- a/spec/fixture/node_modules/grunt-cli/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2012 Tyler Kellen, 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/spec/fixture/node_modules/grunt-cli/README.md b/spec/fixture/node_modules/grunt-cli/README.md deleted file mode 100644 index 8a0b9fec..00000000 --- a/spec/fixture/node_modules/grunt-cli/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# grunt-cli [![Build Status](https://secure.travis-ci.org/gruntjs/grunt-cli.png?branch=master)](http://travis-ci.org/gruntjs/grunt-cli) -> The Grunt command line interface. - -Install this globally and you'll have access to the `grunt` command anywhere on your system. - -```shell -npm install -g grunt-cli -``` - -**Note:** The job of the `grunt` command is to load and run the version of Grunt you have installed locally to your project, irrespective of its version. Starting with Grunt v0.4, you should never install Grunt itself globally. For more information about why, [please read this](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation). - -See the [Getting Started](http://gruntjs.com/getting-started) guide for more information. - -## Shell tab auto-completion -To enable tab auto-completion for Grunt, add one of the following lines to your `~/.bashrc` or `~/.zshrc` file. - -```bash -# Bash, ~/.bashrc -eval "$(grunt --completion=bash)" -``` - -```bash -# Zsh, ~/.zshrc -eval "$(grunt --completion=zsh)" -``` - -## Installing grunt-cli locally -If you prefer the idiomatic Node.js method to get started with a project (`npm install && npm test`) then install grunt-cli locally with `npm install grunt-cli --save-dev`. Then add a script to your `package.json` to run the associated grunt command: `"scripts": { "test": "grunt test" } `. Now `npm test` will use the locally installed `./node_modules/.bin/grunt` executable to run your Grunt commands. - -To read more about npm scripts, please visit the npm docs: [https://npmjs.org/doc/misc/npm-scripts.html](https://npmjs.org/doc/misc/npm-scripts.html). diff --git a/spec/fixture/node_modules/grunt-cli/bin/grunt b/spec/fixture/node_modules/grunt-cli/bin/grunt deleted file mode 100755 index 691f875e..00000000 --- a/spec/fixture/node_modules/grunt-cli/bin/grunt +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node - -'use strict'; - -process.title = 'grunt'; - -// Especially badass external libs. -var findup = require('findup-sync'); -var resolve = require('resolve').sync; - -// Internal libs. -var options = require('../lib/cli').options; -var completion = require('../lib/completion'); -var info = require('../lib/info'); -var path = require('path'); - - -var basedir = process.cwd(); -var gruntpath; - -// Do stuff based on CLI options. -if ('completion' in options) { - completion.print(options.completion); -} else if (options.version) { - info.version(); -} else if (options.base && !options.gruntfile) { - basedir = path.resolve(options.base); -} else if (options.gruntfile) { - basedir = path.resolve(path.dirname(options.gruntfile)); -} - -try { - gruntpath = resolve('grunt', {basedir: basedir}); -} catch (ex) { - gruntpath = findup('lib/grunt.js'); - // No grunt install found! - if (!gruntpath) { - if (options.version) { process.exit(); } - if (options.help) { info.help(); } - info.fatal('Unable to find local grunt.', 99); - } -} - -// Everything looks good. Require local grunt and run it. -require(gruntpath).cli(); diff --git a/spec/fixture/node_modules/grunt-cli/completion/bash b/spec/fixture/node_modules/grunt-cli/completion/bash deleted file mode 100755 index 99a96b5b..00000000 --- a/spec/fixture/node_modules/grunt-cli/completion/bash +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# grunt-cli -# http://gruntjs.com/ -# -# Copyright (c) 2012 Tyler Kellen, contributors -# Licensed under the MIT license. -# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT - -# Usage: -# -# To enable bash completion for grunt, add the following line (minus the -# leading #, which is the bash comment character) to your ~/.bashrc file: -# -# eval "$(grunt --completion=bash)" - -# Search the current directory and all parent directories for a gruntfile. -function _grunt_gruntfile() { - local curpath="$PWD" - while [[ "$curpath" ]]; do - for gruntfile in "$curpath/"{G,g}runtfile.{js,coffee}; do - if [[ -e "$gruntfile" ]]; then - echo "$gruntfile" - return - fi - done - curpath="${curpath%/*}" - done - return 1 -} - -# Enable bash autocompletion. -function _grunt_completions() { - # The currently-being-completed word. - local cur="${COMP_WORDS[COMP_CWORD]}" - # The current gruntfile, if it exists. - local gruntfile="$(_grunt_gruntfile)" - # The current grunt version, available tasks, options, etc. - local gruntinfo="$(grunt --version --verbose 2>/dev/null)" - # Options and tasks. - local opts="$(echo "$gruntinfo" | awk '/Available options: / {$1=$2=""; print $0}')" - local compls="$(echo "$gruntinfo" | awk '/Available tasks: / {$1=$2=""; print $0}')" - # Only add -- or - options if the user has started typing - - [[ "$cur" == -* ]] && compls="$compls $opts" - # Tell complete what stuff to show. - COMPREPLY=($(compgen -W "$compls" -- "$cur")) -} - -complete -o default -F _grunt_completions grunt diff --git a/spec/fixture/node_modules/grunt-cli/completion/zsh b/spec/fixture/node_modules/grunt-cli/completion/zsh deleted file mode 100755 index f39cca26..00000000 --- a/spec/fixture/node_modules/grunt-cli/completion/zsh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/zsh - -# grunt-cli -# http://gruntjs.com/ -# -# Copyright (c) 2012 Tyler Kellen, contributors -# Licensed under the MIT license. -# https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT - -# Usage: -# -# To enable zsh completion for grunt, add the following line (minus the -# leading #, which is the zsh comment character) to your ~/.zshrc file: -# -# eval "$(grunt --completion=zsh)" - -# Enable zsh autocompletion. -function _grunt_completion() { - local completions - # The currently-being-completed word. - local cur="${words[@]}" - # The current grunt version, available tasks, options, etc. - local gruntinfo="$(grunt --version --verbose 2>/dev/null)" - # Options and tasks. - local opts="$(echo "$gruntinfo" | awk '/Available options: / {$1=$2=""; print $0}')" - local compls="$(echo "$gruntinfo" | awk '/Available tasks: / {$1=$2=""; print $0}')" - # Only add -- or - options if the user has started typing - - [[ "$cur" == -* ]] && compls="$compls $opts" - # Trim whitespace. - compls=$(echo "$compls" | sed -e 's/^ *//g' -e 's/ *$//g') - # Turn compls into an array to of completions. - completions=(${=compls}) - # Tell complete what stuff to show. - compadd -- $completions -} - -compdef _grunt_completion grunt diff --git a/spec/fixture/node_modules/grunt-cli/lib/cli.js b/spec/fixture/node_modules/grunt-cli/lib/cli.js deleted file mode 100644 index fc096d40..00000000 --- a/spec/fixture/node_modules/grunt-cli/lib/cli.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * grunt-cli - * http://gruntjs.com/ - * - * Copyright (c) 2012 Tyler Kellen, contributors - * Licensed under the MIT license. - * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT - */ - -'use strict'; - -// External lib. -var nopt = require('nopt'); - -// CLI options we care about. -exports.known = {help: Boolean, version: Boolean, completion: String}; -exports.aliases = {h: '--help', V: '--version', v: '--verbose'}; - -// Parse them and return an options object. -Object.defineProperty(exports, 'options', { - get: function() { - return nopt(exports.known, exports.aliases, process.argv, 2); - } -}); diff --git a/spec/fixture/node_modules/grunt-cli/lib/completion.js b/spec/fixture/node_modules/grunt-cli/lib/completion.js deleted file mode 100644 index eecee06f..00000000 --- a/spec/fixture/node_modules/grunt-cli/lib/completion.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * grunt-cli - * http://gruntjs.com/ - * - * Copyright (c) 2012 Tyler Kellen, contributors - * Licensed under the MIT license. - * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT - */ - -'use strict'; - -// Nodejs libs. -var fs = require('fs'); -var path = require('path'); - -exports.print = function(name) { - var code = 0; - var filepath = path.join(__dirname, '../completion', name); - var output; - try { - // Attempt to read shell completion file. - output = String(fs.readFileSync(filepath)); - } catch (err) { - code = 5; - output = 'echo "Specified grunt shell auto-completion rules '; - if (name && name !== 'true') { - output += 'for \'' + name + '\' '; - } - output += 'not found."'; - } - - console.log(output); - process.exit(code); -}; diff --git a/spec/fixture/node_modules/grunt-cli/lib/info.js b/spec/fixture/node_modules/grunt-cli/lib/info.js deleted file mode 100644 index f128f399..00000000 --- a/spec/fixture/node_modules/grunt-cli/lib/info.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * grunt-cli - * http://gruntjs.com/ - * - * Copyright (c) 2012 Tyler Kellen, contributors - * Licensed under the MIT license. - * https://github.com/gruntjs/grunt-init/blob/master/LICENSE-MIT - */ - -'use strict'; - -// Project metadata. -var pkg = require('../package.json'); - -// Display grunt-cli version. -exports.version = function() { - console.log('grunt-cli v' + pkg.version); -}; - -// Show help, then exit with a message and error code. -exports.fatal = function(msg, code) { - exports.helpHeader(); - console.log('Fatal error: ' + msg); - console.log(''); - exports.helpFooter(); - process.exit(code); -}; - -// Show help and exit. -exports.help = function() { - exports.helpHeader(); - exports.helpFooter(); - process.exit(); -}; - -// Help header. -exports.helpHeader = function() { - console.log('grunt-cli: ' + pkg.description + ' (v' + pkg.version + ')'); - console.log(''); -}; - -// Help footer. -exports.helpFooter = function() { - [ - 'If you\'re seeing this message, either a Gruntfile wasn\'t found or grunt', - 'hasn\'t been installed locally to your project. For more information about', - 'installing and configuring grunt, please see the Getting Started guide:', - '', - 'http://gruntjs.com/getting-started', - ].forEach(function(str) { console.log(str); }); -}; diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt b/spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt deleted file mode 120000 index 6b6566ea..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/.bin/nopt +++ /dev/null @@ -1 +0,0 @@ -../nopt/bin/nopt.js \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc deleted file mode 100644 index 87189522..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.jshintrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "loopfunc": true, - "curly": true, - "eqeqeq": true, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "sub": true, - "undef": true, - "unused": true, - "boss": true, - "eqnull": true, - "node": true -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.npmignore deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml deleted file mode 100644 index b30fcb75..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.8 -before_script: - - npm install -g grunt-cli diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js deleted file mode 100644 index 2f964a5b..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/Gruntfile.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -module.exports = function(grunt) { - - // Project configuration. - grunt.initConfig({ - nodeunit: { - files: ['test/**/*_test.js'], - }, - jshint: { - options: { - jshintrc: '.jshintrc' - }, - all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'] - } - }); - - // Load plugins. - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-nodeunit'); - - // Default task. - grunt.registerTask('default', ['jshint', 'nodeunit']); - -}; diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT deleted file mode 100644 index bb2aad6d..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 "Cowboy" Ben Alman - -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/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md deleted file mode 100644 index 5459b93f..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# findup-sync [![Build Status](https://secure.travis-ci.org/cowboy/node-findup-sync.png?branch=master)](http://travis-ci.org/cowboy/node-findup-sync) - -Find the first file matching a given pattern in the current directory or the nearest ancestor directory. - -## Getting Started -Install the module with: `npm install findup-sync` - -```js -var findup = require('findup-sync'); - -// Start looking in the CWD. -var filepath1 = findup('{a,b}*.txt'); - -// Start looking somewhere else, and ignore case (probably a good idea). -var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true}); -``` - -## Usage - -```js -findup(patternOrPatterns [, minimatchOptions]) -``` - -### patternOrPatterns -Type: `String` or `Array` -Default: none - -One or more wildcard glob patterns. Or just filenames. - -### minimatchOptions -Type: `Object` -Default: `{}` - -Options to be passed to [minimatch](https://github.com/isaacs/minimatch). - -Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here. - -## Contributing -In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). - -## Release History -2014-03-14 - v0.1.3 - Updated dependencies. -2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform. -2012-11-15 - v0.1.1 - Now works without an options object. -2012-11-01 - v0.1.0 - Initial release. diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js deleted file mode 100644 index 742a4781..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/lib/findup-sync.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * findup-sync - * https://github.com/cowboy/node-findup-sync - * - * Copyright (c) 2013 "Cowboy" Ben Alman - * Licensed under the MIT license. - */ - -'use strict'; - -// Nodejs libs. -var path = require('path'); - -// External libs. -var glob = require('glob'); -var _ = require('lodash'); - -// Search for a filename in the given directory or all parent directories. -module.exports = function(patterns, options) { - // Normalize patterns to an array. - if (!Array.isArray(patterns)) { patterns = [patterns]; } - // Create globOptions so that it can be modified without mutating the - // original object. - var globOptions = Object.create(options || {}); - globOptions.maxDepth = 1; - globOptions.cwd = path.resolve(globOptions.cwd || '.'); - - var files, lastpath; - do { - // Search for files matching patterns. - files = _(patterns).map(function(pattern) { - return glob.sync(pattern, globOptions); - }).flatten().uniq().value(); - // Return file if found. - if (files.length > 0) { - return path.resolve(path.join(globOptions.cwd, files[0])); - } - // Go up a directory. - lastpath = globOptions.cwd; - globOptions.cwd = path.resolve(globOptions.cwd, '..'); - // If parentpath is the same as basedir, we can't go any higher. - } while (globOptions.cwd !== lastpath); - - // No files were found! - return null; -}; diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore deleted file mode 100644 index 2af4b71c..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -.*.swp -test/a/ diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml deleted file mode 100644 index baa0031d..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - 0.8 diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE deleted file mode 100644 index 0c44ae71..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) Isaac Z. Schlueter ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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 AUTHOR 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 AUTHOR 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/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md deleted file mode 100644 index cc691645..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# Glob - -Match files using the patterns the shell uses, like stars and stuff. - -This is a glob implementation in JavaScript. It uses the `minimatch` -library to do its matching. - -## Attention: node-glob users! - -The API has changed dramatically between 2.x and 3.x. This library is -now 100% JavaScript, and the integer flags have been replaced with an -options object. - -Also, there's an event emitter class, proper tests, and all the other -things you've come to expect from node modules. - -And best of all, no compilation! - -## Usage - -```javascript -var glob = require("glob") - -// options is optional -glob("**/*.js", options, function (er, files) { - // files is an array of filenames. - // If the `nonull` option is set, and nothing - // was found, then files is ["**/*.js"] - // er is an error object or null. -}) -``` - -## Features - -Please see the [minimatch -documentation](https://github.com/isaacs/minimatch) for more details. - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` -* [minimatch documentation](https://github.com/isaacs/minimatch) - -## glob(pattern, [options], cb) - -* `pattern` {String} Pattern to be matched -* `options` {Object} -* `cb` {Function} - * `err` {Error | null} - * `matches` {Array} filenames found matching the pattern - -Perform an asynchronous glob search. - -## glob.sync(pattern, [options]) - -* `pattern` {String} Pattern to be matched -* `options` {Object} -* return: {Array} filenames found matching the pattern - -Perform a synchronous glob search. - -## Class: glob.Glob - -Create a Glob object by instanting the `glob.Glob` class. - -```javascript -var Glob = require("glob").Glob -var mg = new Glob(pattern, options, cb) -``` - -It's an EventEmitter, and starts walking the filesystem to find matches -immediately. - -### new glob.Glob(pattern, [options], [cb]) - -* `pattern` {String} pattern to search for -* `options` {Object} -* `cb` {Function} Called when an error occurs, or matches are found - * `err` {Error | null} - * `matches` {Array} filenames found matching the pattern - -Note that if the `sync` flag is set in the options, then matches will -be immediately available on the `g.found` member. - -### Properties - -* `minimatch` The minimatch object that the glob uses. -* `options` The options object passed in. -* `error` The error encountered. When an error is encountered, the - glob object is in an undefined state, and should be discarded. -* `aborted` Boolean which is set to true when calling `abort()`. There - is no way at this time to continue a glob search after aborting, but - you can re-use the statCache to avoid having to duplicate syscalls. -* `statCache` Collection of all the stat results the glob search - performed. -* `cache` Convenience object. Each field has the following possible - values: - * `false` - Path does not exist - * `true` - Path exists - * `1` - Path exists, and is not a directory - * `2` - Path exists, and is a directory - * `[file, entries, ...]` - Path exists, is a directory, and the - array value is the results of `fs.readdir` - -### Events - -* `end` When the matching is finished, this is emitted with all the - matches found. If the `nonull` option is set, and no match was found, - then the `matches` list contains the original pattern. The matches - are sorted, unless the `nosort` flag is set. -* `match` Every time a match is found, this is emitted with the matched. -* `error` Emitted when an unexpected error is encountered, or whenever - any fs error occurs if `options.strict` is set. -* `abort` When `abort()` is called, this event is raised. - -### Methods - -* `abort` Stop the search. - -### Options - -All the options that can be passed to Minimatch can also be passed to -Glob to change pattern matching behavior. Also, some have been added, -or have glob-specific ramifications. - -All options are false by default, unless otherwise noted. - -All options are added to the glob object, as well. - -* `cwd` The current working directory in which to search. Defaults - to `process.cwd()`. -* `root` The place where patterns starting with `/` will be mounted - onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix - systems, and `C:\` or some such on Windows.) -* `dot` Include `.dot` files in normal matches and `globstar` matches. - Note that an explicit dot in a portion of the pattern will always - match dot files. -* `nomount` By default, a pattern starting with a forward-slash will be - "mounted" onto the root setting, so that a valid filesystem path is - returned. Set this flag to disable that behavior. -* `mark` Add a `/` character to directory matches. Note that this - requires additional stat calls. -* `nosort` Don't sort the results. -* `stat` Set to true to stat *all* results. This reduces performance - somewhat, and is completely unnecessary, unless `readdir` is presumed - to be an untrustworthy indicator of file existence. It will cause - ELOOP to be triggered one level sooner in the case of cyclical - symbolic links. -* `silent` When an unusual error is encountered - when attempting to read a directory, a warning will be printed to - stderr. Set the `silent` option to true to suppress these warnings. -* `strict` When an unusual error is encountered - when attempting to read a directory, the process will just continue on - in search of other matches. Set the `strict` option to raise an error - in these cases. -* `cache` See `cache` property above. Pass in a previously generated - cache object to save some fs calls. -* `statCache` A cache of results of filesystem information, to prevent - unnecessary stat calls. While it should not normally be necessary to - set this, you may pass the statCache from one glob() call to the - options object of another, if you know that the filesystem will not - change between calls. (See "Race Conditions" below.) -* `sync` Perform a synchronous glob search. -* `nounique` In some cases, brace-expanded patterns can result in the - same file showing up multiple times in the result set. By default, - this implementation prevents duplicates in the result set. - Set this flag to disable that behavior. -* `nonull` Set to never return an empty set, instead returning a set - containing the pattern itself. This is the default in glob(3). -* `nocase` Perform a case-insensitive match. Note that case-insensitive - filesystems will sometimes result in glob returning results that are - case-insensitively matched anyway, since readdir and stat will not - raise an error. -* `debug` Set to enable debug logging in minimatch and glob. -* `globDebug` Set to enable debug logging in glob, but not minimatch. - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between node-glob and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then glob returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. - -## Windows - -**Please only use forward-slashes in glob expressions.** - -Though windows uses either `/` or `\` as its path separator, only `/` -characters are used by this glob implementation. You must use -forward-slashes **only** in glob expressions. Back-slashes will always -be interpreted as escape characters, not path separators. - -Results from absolute patterns such as `/foo/*` are mounted onto the -root setting using `path.join`. On windows, this will by default result -in `/foo/*` matching `C:\foo\bar.txt`. - -## Race Conditions - -Glob searching, by its very nature, is susceptible to race conditions, -since it relies on directory walking and such. - -As a result, it is possible that a file that exists when glob looks for -it may have been deleted or modified by the time it returns the result. - -As part of its internal implementation, this program caches all stat -and readdir calls that it makes, in order to cut down on system -overhead. However, this also makes it even more susceptible to races, -especially if the cache or statCache objects are reused between glob -calls. - -Users are thus advised not to use a glob result as a guarantee of -filesystem state in the face of rapid changes. For the vast majority -of operations, this is never a problem. diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js deleted file mode 100644 index be122df0..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/g.js +++ /dev/null @@ -1,9 +0,0 @@ -var Glob = require("../").Glob - -var pattern = "test/a/**/[cg]/../[cg]" -console.log(pattern) - -var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { - console.log("matches", matches) -}) -console.log("after") diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js deleted file mode 100644 index 327a425e..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/examples/usr-local.js +++ /dev/null @@ -1,9 +0,0 @@ -var Glob = require("../").Glob - -var pattern = "{./*/*,/*,/usr/local/*}" -console.log(pattern) - -var mg = new Glob(pattern, {mark: true}, function (er, matches) { - console.log("matches", matches) -}) -console.log("after") diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js deleted file mode 100644 index f646c448..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/glob.js +++ /dev/null @@ -1,728 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// readdir(PREFIX) as ENTRIES -// If fails, END -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $]) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $]) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - - - -module.exports = glob - -var fs = require("fs") -, minimatch = require("minimatch") -, Minimatch = minimatch.Minimatch -, inherits = require("inherits") -, EE = require("events").EventEmitter -, path = require("path") -, isDir = {} -, assert = require("assert").ok - -function glob (pattern, options, cb) { - if (typeof options === "function") cb = options, options = {} - if (!options) options = {} - - if (typeof options === "number") { - deprecated() - return - } - - var g = new Glob(pattern, options, cb) - return g.sync ? g.found : g -} - -glob.fnmatch = deprecated - -function deprecated () { - throw new Error("glob's interface has changed. Please see the docs.") -} - -glob.sync = globSync -function globSync (pattern, options) { - if (typeof options === "number") { - deprecated() - return - } - - options = options || {} - options.sync = true - return glob(pattern, options) -} - -this._processingEmitQueue = false - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (!(this instanceof Glob)) { - return new Glob(pattern, options, cb) - } - - if (typeof options === "function") { - cb = options - options = null - } - - if (typeof cb === "function") { - this.on("error", cb) - this.on("end", function (matches) { - cb(null, matches) - }) - } - - options = options || {} - - this._endEmitted = false - this.EOF = {} - this._emitQueue = [] - - this.paused = false - this._processingEmitQueue = false - - this.maxDepth = options.maxDepth || 1000 - this.maxLength = options.maxLength || Infinity - this.cache = options.cache || {} - this.statCache = options.statCache || {} - - this.changedCwd = false - var cwd = process.cwd() - if (!options.hasOwnProperty("cwd")) this.cwd = cwd - else { - this.cwd = options.cwd - this.changedCwd = path.resolve(options.cwd) !== cwd - } - - this.root = options.root || path.resolve(this.cwd, "/") - this.root = path.resolve(this.root) - if (process.platform === "win32") - this.root = this.root.replace(/\\/g, "/") - - this.nomount = !!options.nomount - - if (!pattern) { - throw new Error("must provide pattern") - } - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - this.strict = options.strict !== false - this.dot = !!options.dot - this.mark = !!options.mark - this.sync = !!options.sync - this.nounique = !!options.nounique - this.nonull = !!options.nonull - this.nosort = !!options.nosort - this.nocase = !!options.nocase - this.stat = !!options.stat - - this.debug = !!options.debug || !!options.globDebug - if (this.debug) - this.log = console.error - - this.silent = !!options.silent - - var mm = this.minimatch = new Minimatch(pattern, options) - this.options = mm.options - pattern = this.pattern = mm.pattern - - this.error = null - this.aborted = false - - // list of all the patterns that ** has resolved do, so - // we can avoid visiting multiple times. - this._globstars = {} - - EE.call(this) - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - this.minimatch.set.forEach(iterator.bind(this)) - function iterator (pattern, i, set) { - this._process(pattern, 0, i, function (er) { - if (er) this.emit("error", er) - if (-- n <= 0) this._finish() - }) - } -} - -Glob.prototype.log = function () {} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - - var nou = this.nounique - , all = nou ? [] : {} - - for (var i = 0, l = this.matches.length; i < l; i ++) { - var matches = this.matches[i] - this.log("matches[%d] =", i, matches) - // do like the shell, and spit out the literal glob - if (!matches) { - if (this.nonull) { - var literal = this.minimatch.globSet[i] - if (nou) all.push(literal) - else all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) all.push.apply(all, m) - else m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) all = Object.keys(all) - - if (!this.nosort) { - all = all.sort(this.nocase ? alphasorti : alphasort) - } - - if (this.mark) { - // at *some* point we statted all of these - all = all.map(this._mark, this) - } - - this.log("emitting end", all) - - this.EOF = this.found = all - this.emitMatch(this.EOF) -} - -function alphasorti (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return alphasort(a, b) -} - -function alphasort (a, b) { - return a > b ? 1 : a < b ? -1 : 0 -} - -Glob.prototype._mark = function (p) { - var c = this.cache[p] - var m = p - if (c) { - var isDir = c === 2 || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - this.statCache[m] = this.statCache[p] - this.cache[m] = this.cache[p] - } - } - - return m -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit("abort") -} - -Glob.prototype.pause = function () { - if (this.paused) return - if (this.sync) - this.emit("error", new Error("Can't pause/resume sync glob")) - this.paused = true - this.emit("pause") -} - -Glob.prototype.resume = function () { - if (!this.paused) return - if (this.sync) - this.emit("error", new Error("Can't pause/resume sync glob")) - this.paused = false - this.emit("resume") - this._processEmitQueue() - //process.nextTick(this.emit.bind(this, "resume")) -} - -Glob.prototype.emitMatch = function (m) { - this.log('emitMatch', m) - this._emitQueue.push(m) - this._processEmitQueue() -} - -Glob.prototype._processEmitQueue = function (m) { - this.log("pEQ paused=%j processing=%j m=%j", this.paused, - this._processingEmitQueue, m) - var done = false - while (!this._processingEmitQueue && - !this.paused) { - this._processingEmitQueue = true - var m = this._emitQueue.shift() - this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m) - if (!m) { - this.log(">processEmitQueue, falsey m") - this._processingEmitQueue = false - break - } - - if (m === this.EOF || !(this.mark && !this.stat)) { - this.log("peq: unmarked, or eof") - next.call(this, 0, false) - } else if (this.statCache[m]) { - var sc = this.statCache[m] - var exists - if (sc) - exists = sc.isDirectory() ? 2 : 1 - this.log("peq: stat cached") - next.call(this, exists, exists === 2) - } else { - this.log("peq: _stat, then next") - this._stat(m, next) - } - - function next(exists, isDir) { - this.log("next", m, exists, isDir) - var ev = m === this.EOF ? "end" : "match" - - // "end" can only happen once. - assert(!this._endEmitted) - if (ev === "end") - this._endEmitted = true - - if (exists) { - // Doesn't mean it necessarily doesn't exist, it's possible - // we just didn't check because we don't care that much, or - // this is EOF anyway. - if (isDir && !m.match(/\/$/)) { - m = m + "/" - } else if (!isDir && m.match(/\/$/)) { - m = m.replace(/\/+$/, "") - } - } - this.log("emit", ev, m) - this.emit(ev, m) - this._processingEmitQueue = false - if (done && m !== this.EOF && !this.paused) - this._processEmitQueue() - } - } - done = true -} - -Glob.prototype._process = function (pattern, depth, index, cb_) { - assert(this instanceof Glob) - - var cb = function cb (er, res) { - assert(this instanceof Glob) - if (this.paused) { - if (!this._processQueue) { - this._processQueue = [] - this.once("resume", function () { - var q = this._processQueue - this._processQueue = null - q.forEach(function (cb) { cb() }) - }) - } - this._processQueue.push(cb_.bind(this, er, res)) - } else { - cb_.call(this, er, res) - } - }.bind(this) - - if (this.aborted) return cb() - - if (depth > this.maxDepth) return cb() - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === "string") { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - prefix = pattern.join("/") - this._stat(prefix, function (exists, isDir) { - // either it's there, or it isn't. - // nothing more to do, either way. - if (exists) { - if (prefix && isAbsolute(prefix) && !this.nomount) { - if (prefix.charAt(0) === "/") { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - } - } - - if (process.platform === "win32") - prefix = prefix.replace(/\\/g, "/") - - this.matches[index] = this.matches[index] || {} - this.matches[index][prefix] = true - this.emitMatch(prefix) - } - return cb() - }) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's "absolute" like /foo/bar, - // or "relative" like "../baz" - prefix = pattern.slice(0, n) - prefix = prefix.join("/") - break - } - - // get the list of entries. - var read - if (prefix === null) read = "." - else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) { - if (!prefix || !isAbsolute(prefix)) { - prefix = path.join("/", prefix) - } - read = prefix = path.resolve(prefix) - - // if (process.platform === "win32") - // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/") - - this.log('absolute: ', prefix, this.root, pattern, read) - } else { - read = prefix - } - - this.log('readdir(%j)', read, this.cwd, this.root) - - return this._readdir(read, function (er, entries) { - if (er) { - // not a directory! - // this means that, whatever else comes after this, it can never match - return cb() - } - - // globstar is special - if (pattern[n] === minimatch.GLOBSTAR) { - // test without the globstar, and with every child both below - // and replacing the globstar. - var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ] - entries.forEach(function (e) { - if (e.charAt(0) === "." && !this.dot) return - // instead of the globstar - s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) - // below the globstar - s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n))) - }, this) - - s = s.filter(function (pattern) { - var key = gsKey(pattern) - var seen = !this._globstars[key] - this._globstars[key] = true - return seen - }, this) - - if (!s.length) - return cb() - - // now asyncForEach over this - var l = s.length - , errState = null - s.forEach(function (gsPattern) { - this._process(gsPattern, depth + 1, index, function (er) { - if (errState) return - if (er) return cb(errState = er) - if (--l <= 0) return cb() - }) - }, this) - - return - } - - // not a globstar - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = pattern[n] - var rawGlob = pattern[n]._glob - , dotOk = this.dot || rawGlob.charAt(0) === "." - - entries = entries.filter(function (e) { - return (e.charAt(0) !== "." || dotOk) && - e.match(pattern[n]) - }) - - // If n === pattern.length - 1, then there's no need for the extra stat - // *unless* the user has specified "mark" or "stat" explicitly. - // We know that they exist, since the readdir returned them. - if (n === pattern.length - 1 && - !this.mark && - !this.stat) { - entries.forEach(function (e) { - if (prefix) { - if (prefix !== "/") e = prefix + "/" + e - else e = prefix + e - } - if (e.charAt(0) === "/" && !this.nomount) { - e = path.join(this.root, e) - } - - if (process.platform === "win32") - e = e.replace(/\\/g, "/") - - this.matches[index] = this.matches[index] || {} - this.matches[index][e] = true - this.emitMatch(e) - }, this) - return cb.call(this) - } - - - // now test all the remaining entries as stand-ins for that part - // of the pattern. - var l = entries.length - , errState = null - if (l === 0) return cb() // no matches possible - entries.forEach(function (e) { - var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) - this._process(p, depth + 1, index, function (er) { - if (errState) return - if (er) return cb(errState = er) - if (--l === 0) return cb.call(this) - }) - }, this) - }) - -} - -function gsKey (pattern) { - return '**' + pattern.map(function (p) { - return (p === minimatch.GLOBSTAR) ? '**' : (''+p) - }).join('/') -} - -Glob.prototype._stat = function (f, cb) { - assert(this instanceof Glob) - var abs = f - if (f.charAt(0) === "/") { - abs = path.join(this.root, f) - } else if (this.changedCwd) { - abs = path.resolve(this.cwd, f) - } - - if (f.length > this.maxLength) { - var er = new Error("Path name too long") - er.code = "ENAMETOOLONG" - er.path = f - return this._afterStat(f, abs, cb, er) - } - - this.log('stat', [this.cwd, f, '=', abs]) - - if (!this.stat && this.cache.hasOwnProperty(f)) { - var exists = this.cache[f] - , isDir = exists && (Array.isArray(exists) || exists === 2) - if (this.sync) return cb.call(this, !!exists, isDir) - return process.nextTick(cb.bind(this, !!exists, isDir)) - } - - var stat = this.statCache[abs] - if (this.sync || stat) { - var er - try { - stat = fs.statSync(abs) - } catch (e) { - er = e - } - this._afterStat(f, abs, cb, er, stat) - } else { - fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) - } -} - -Glob.prototype._afterStat = function (f, abs, cb, er, stat) { - var exists - assert(this instanceof Glob) - - if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) { - this.log("should be ENOTDIR, fake it") - - er = new Error("ENOTDIR, not a directory '" + abs + "'") - er.path = abs - er.code = "ENOTDIR" - stat = null - } - - var emit = !this.statCache[abs] - this.statCache[abs] = stat - - if (er || !stat) { - exists = false - } else { - exists = stat.isDirectory() ? 2 : 1 - if (emit) - this.emit('stat', f, stat) - } - this.cache[f] = this.cache[f] || exists - cb.call(this, !!exists, exists === 2) -} - -Glob.prototype._readdir = function (f, cb) { - assert(this instanceof Glob) - var abs = f - if (f.charAt(0) === "/") { - abs = path.join(this.root, f) - } else if (isAbsolute(f)) { - abs = f - } else if (this.changedCwd) { - abs = path.resolve(this.cwd, f) - } - - if (f.length > this.maxLength) { - var er = new Error("Path name too long") - er.code = "ENAMETOOLONG" - er.path = f - return this._afterReaddir(f, abs, cb, er) - } - - this.log('readdir', [this.cwd, f, abs]) - if (this.cache.hasOwnProperty(f)) { - var c = this.cache[f] - if (Array.isArray(c)) { - if (this.sync) return cb.call(this, null, c) - return process.nextTick(cb.bind(this, null, c)) - } - - if (!c || c === 1) { - // either ENOENT or ENOTDIR - var code = c ? "ENOTDIR" : "ENOENT" - , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) - er.path = f - er.code = code - this.log(f, er) - if (this.sync) return cb.call(this, er) - return process.nextTick(cb.bind(this, er)) - } - - // at this point, c === 2, meaning it's a dir, but we haven't - // had to read it yet, or c === true, meaning it's *something* - // but we don't have any idea what. Need to read it, either way. - } - - if (this.sync) { - var er, entries - try { - entries = fs.readdirSync(abs) - } catch (e) { - er = e - } - return this._afterReaddir(f, abs, cb, er, entries) - } - - fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) -} - -Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { - assert(this instanceof Glob) - if (entries && !er) { - this.cache[f] = entries - // if we haven't asked to stat everything for suresies, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. This also gets us one step - // further into ELOOP territory. - if (!this.mark && !this.stat) { - entries.forEach(function (e) { - if (f === "/") e = f + e - else e = f + "/" + e - this.cache[e] = true - }, this) - } - - return cb.call(this, er, entries) - } - - // now handle errors, and cache the information - if (er) switch (er.code) { - case "ENOTDIR": // totally normal. means it *does* exist. - this.cache[f] = 1 - return cb.call(this, er) - case "ENOENT": // not terribly unusual - case "ELOOP": - case "ENAMETOOLONG": - case "UNKNOWN": - this.cache[f] = false - return cb.call(this, er) - default: // some unusual error. Treat as failure. - this.cache[f] = false - if (this.strict) this.emit("error", er) - if (!this.silent) console.error("glob error", er) - return cb.call(this, er) - } -} - -var isAbsolute = process.platform === "win32" ? absWin : absUnix - -function absWin (p) { - if (absUnix(p)) return true - // pull off the device/UNC bit from a windows path. - // from node's lib/path.js - var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/ - , result = splitDeviceRe.exec(p) - , device = result[1] || '' - , isUnc = device && device.charAt(1) !== ':' - , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute - - return isAbsolute -} - -function absUnix (p) { - return p.charAt(0) === "/" || p === "" -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE deleted file mode 100644 index dea3013d..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -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/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md deleted file mode 100644 index b1c56658..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md +++ /dev/null @@ -1,42 +0,0 @@ -Browser-friendly inheritance fully compatible with standard node.js -[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). - -This package exports standard `inherits` from node.js `util` module in -node environment, but also provides alternative browser-friendly -implementation through [browser -field](https://gist.github.com/shtylman/4339901). Alternative -implementation is a literal copy of standard one located in standalone -module to avoid requiring of `util`. It also has a shim for old -browsers with no `Object.create` support. - -While keeping you sure you are using standard `inherits` -implementation in node.js environment, it allows bundlers such as -[browserify](https://github.com/substack/node-browserify) to not -include full `util` package to your client code if all you need is -just `inherits` function. It worth, because browser shim for `util` -package is large and `inherits` is often the single function you need -from it. - -It's recommended to use this package instead of -`require('util').inherits` for any code that has chances to be used -not only in node.js but in browser too. - -## usage - -```js -var inherits = require('inherits'); -// then use exactly as the standard one -``` - -## note on version ~1.0 - -Version ~1.0 had completely different motivation and is not compatible -neither with 2.0 nor with standard node.js `inherits`. - -If you are using version ~1.0 and planning to switch to ~2.0, be -careful: - -* new version uses `super_` instead of `super` for referencing - superclass -* new version overwrites current prototype while old one preserves any - existing fields on it diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js deleted file mode 100644 index 29f5e24f..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('util').inherits diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js deleted file mode 100644 index c1e78a75..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js +++ /dev/null @@ -1,23 +0,0 @@ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json deleted file mode 100644 index 754a1144..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "inherits", - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "version": "2.0.1", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "main": "./inherits.js", - "browser": "./inherits_browser.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/inherits" - }, - "license": "ISC", - "scripts": { - "test": "node test" - }, - "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/isaacs/inherits/issues" - }, - "_id": "inherits@2.0.1", - "dist": { - "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "_from": "inherits@2", - "_npmVersion": "1.3.8", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "homepage": "https://github.com/isaacs/inherits" -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js deleted file mode 100644 index fc53012d..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js +++ /dev/null @@ -1,25 +0,0 @@ -var inherits = require('./inherits.js') -var assert = require('assert') - -function test(c) { - assert(c.constructor === Child) - assert(c.constructor.super_ === Parent) - assert(Object.getPrototypeOf(c) === Child.prototype) - assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) - assert(c instanceof Child) - assert(c instanceof Parent) -} - -function Child() { - Parent.call(this) - test(this) -} - -function Parent() {} - -inherits(Child, Parent) - -var c = new Child -test(c) - -console.log('ok') diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore deleted file mode 100644 index 3c3629e6..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE deleted file mode 100644 index 05a40109..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -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/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md deleted file mode 100644 index 5b3967ea..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md +++ /dev/null @@ -1,218 +0,0 @@ -# minimatch - -A minimal matching utility. - -[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch) - - -This is the matching library used internally by npm. - -Eventually, it will replace the C binding in node-glob. - -It works by converting glob expressions into JavaScript `RegExp` -objects. - -## Usage - -```javascript -var minimatch = require("minimatch") - -minimatch("bar.foo", "*.foo") // true! -minimatch("bar.foo", "*.bar") // false! -minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! -``` - -## Features - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` - -## Minimatch Class - -Create a minimatch object by instanting the `minimatch.Minimatch` class. - -```javascript -var Minimatch = require("minimatch").Minimatch -var mm = new Minimatch(pattern, options) -``` - -### Properties - -* `pattern` The original pattern the minimatch object represents. -* `options` The options supplied to the constructor. -* `set` A 2-dimensional array of regexp or string expressions. - Each row in the - array corresponds to a brace-expanded pattern. Each item in the row - corresponds to a single path-part. For example, the pattern - `{a,b/c}/d` would expand to a set of patterns like: - - [ [ a, d ] - , [ b, c, d ] ] - - If a portion of the pattern doesn't have any "magic" in it - (that is, it's something like `"foo"` rather than `fo*o?`), then it - will be left as a string rather than converted to a regular - expression. - -* `regexp` Created by the `makeRe` method. A single regular expression - expressing the entire pattern. This is useful in cases where you wish - to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. -* `negate` True if the pattern is negated. -* `comment` True if the pattern is a comment. -* `empty` True if the pattern is `""`. - -### Methods - -* `makeRe` Generate the `regexp` member if necessary, and return it. - Will return `false` if the pattern is invalid. -* `match(fname)` Return true if the filename matches the pattern, or - false otherwise. -* `matchOne(fileArray, patternArray, partial)` Take a `/`-split - filename, and match it against a single row in the `regExpSet`. This - method is mainly for internal use, but is exposed so that it can be - used by a glob-walker that needs to avoid excessive filesystem calls. - -All other methods are internal, and will be called as necessary. - -## Functions - -The top-level exported function has a `cache` property, which is an LRU -cache set to store 100 items. So, calling these methods repeatedly -with the same pattern and options will use the same Minimatch object, -saving the cost of parsing it multiple times. - -### minimatch(path, pattern, options) - -Main export. Tests a path against the pattern using the options. - -```javascript -var isJS = minimatch(file, "*.js", { matchBase: true }) -``` - -### minimatch.filter(pattern, options) - -Returns a function that tests its -supplied argument, suitable for use with `Array.filter`. Example: - -```javascript -var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) -``` - -### minimatch.match(list, pattern, options) - -Match against the list of -files, in the style of fnmatch or glob. If nothing is matched, and -options.nonull is set, then return a list containing the pattern itself. - -```javascript -var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) -``` - -### minimatch.makeRe(pattern, options) - -Make a regular expression object from the pattern. - -## Options - -All options are `false` by default. - -### debug - -Dump a ton of stuff to stderr. - -### nobrace - -Do not expand `{a,b}` and `{1..3}` brace sets. - -### noglobstar - -Disable `**` matching against multiple folder names. - -### dot - -Allow patterns to match filenames starting with a period, even if -the pattern does not explicitly have a period in that spot. - -Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` -is set. - -### noext - -Disable "extglob" style patterns like `+(a|b)`. - -### nocase - -Perform a case-insensitive match. - -### nonull - -When a match is not found by `minimatch.match`, return a list containing -the pattern itself if this option is set. When not set, an empty list -is returned if there are no matches. - -### matchBase - -If set, then patterns without slashes will be matched -against the basename of the path if it contains slashes. For example, -`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. - -### nocomment - -Suppress the behavior of treating `#` at the start of a pattern as a -comment. - -### nonegate - -Suppress the behavior of treating a leading `!` character as negation. - -### flipNegate - -Returns from negate expressions the same as if they were not negated. -(Ie, true on a hit, false on a miss.) - - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between minimatch and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then minimatch.match returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js deleted file mode 100644 index 45396789..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,1061 +0,0 @@ -;(function (require, exports, module, platform) { - -if (module) module.exports = minimatch -else exports.minimatch = minimatch - -if (!require) { - require = function (id) { - switch (id) { - case "sigmund": return function sigmund (obj) { - return JSON.stringify(obj) - } - case "path": return { basename: function (f) { - f = f.split(/[\/\\]/) - var e = f.pop() - if (!e) e = f.pop() - return e - }} - case "lru-cache": return function LRUCache () { - // not quite an LRU, but still space-limited. - var cache = {} - var cnt = 0 - this.set = function (k, v) { - cnt ++ - if (cnt >= 100) cache = {} - cache[k] = v - } - this.get = function (k) { return cache[k] } - } - } - } -} - -minimatch.Minimatch = Minimatch - -var LRU = require("lru-cache") - , cache = minimatch.cache = new LRU({max: 100}) - , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} - , sigmund = require("sigmund") - -var path = require("path") - // any single thing other than / - // don't need to escape / when using new RegExp() - , qmark = "[^/]" - - // * => any number of characters - , star = qmark + "*?" - - // ** when dots are allowed. Anything goes, except .. and . - // not (^ or / followed by one or two dots followed by $ or /), - // followed by anything, any number of times. - , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" - - // not a ^ or / followed by a dot, - // followed by anything, any number of times. - , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" - - // characters that need to be escaped in RegExp. - , reSpecials = charSet("().*{}+?[]^$\\!") - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split("").reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - - -function minimatch (p, pattern, options) { - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required") - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === "#") { - return false - } - - // "" only matches "" - if (pattern.trim() === "") return p === "" - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options, cache) - } - - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required") - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. - if (platform === "win32") { - pattern = pattern.split("\\").join("/") - } - - // lru storage. - // these things aren't particularly big, but walking down the string - // and turning it into a regexp can get pretty costly. - var cacheKey = pattern + "\n" + sigmund(options) - var cached = minimatch.cache.get(cacheKey) - if (cached) return cached - minimatch.cache.set(cacheKey, this) - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function() {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === "#") { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return -1 === s.indexOf(false) - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - , negate = false - , options = this.options - , negateOffset = 0 - - if (options.nonegate) return - - for ( var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === "!" - ; i ++) { - negate = !negate - negateOffset ++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return new Minimatch(pattern, options).braceExpand() -} - -Minimatch.prototype.braceExpand = braceExpand -function braceExpand (pattern, options) { - options = options || this.options - pattern = typeof pattern === "undefined" - ? this.pattern : pattern - - if (typeof pattern === "undefined") { - throw new Error("undefined pattern") - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - var escaping = false - - // examples and comments refer to this crazy pattern: - // a{b,c{d,e},{f,g}h}x{y,z} - // expected: - // abxy - // abxz - // acdxy - // acdxz - // acexy - // acexz - // afhxy - // afhxz - // aghxy - // aghxz - - // everything before the first \{ is just a prefix. - // So, we pluck that off, and work with the rest, - // and then prepend it to everything we find. - if (pattern.charAt(0) !== "{") { - this.debug(pattern) - var prefix = null - for (var i = 0, l = pattern.length; i < l; i ++) { - var c = pattern.charAt(i) - this.debug(i, c) - if (c === "\\") { - escaping = !escaping - } else if (c === "{" && !escaping) { - prefix = pattern.substr(0, i) - break - } - } - - // actually no sets, all { were escaped. - if (prefix === null) { - this.debug("no sets") - return [pattern] - } - - var tail = braceExpand.call(this, pattern.substr(i), options) - return tail.map(function (t) { - return prefix + t - }) - } - - // now we have something like: - // {b,c{d,e},{f,g}h}x{y,z} - // walk through the set, expanding each part, until - // the set ends. then, we'll expand the suffix. - // If the set only has a single member, then'll put the {} back - - // first, handle numeric sets, since they're easier - var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/) - if (numset) { - this.debug("numset", numset[1], numset[2]) - var suf = braceExpand.call(this, pattern.substr(numset[0].length), options) - , start = +numset[1] - , end = +numset[2] - , inc = start > end ? -1 : 1 - , set = [] - for (var i = start; i != (end + inc); i += inc) { - // append all the suffixes - for (var ii = 0, ll = suf.length; ii < ll; ii ++) { - set.push(i + suf[ii]) - } - } - return set - } - - // ok, walk through the set - // We hope, somewhat optimistically, that there - // will be a } at the end. - // If the closing brace isn't found, then the pattern is - // interpreted as braceExpand("\\" + pattern) so that - // the leading \{ will be interpreted literally. - var i = 1 // skip the \{ - , depth = 1 - , set = [] - , member = "" - , sawEnd = false - , escaping = false - - function addMember () { - set.push(member) - member = "" - } - - this.debug("Entering for") - FOR: for (i = 1, l = pattern.length; i < l; i ++) { - var c = pattern.charAt(i) - this.debug("", i, c) - - if (escaping) { - escaping = false - member += "\\" + c - } else { - switch (c) { - case "\\": - escaping = true - continue - - case "{": - depth ++ - member += "{" - continue - - case "}": - depth -- - // if this closes the actual set, then we're done - if (depth === 0) { - addMember() - // pluck off the close-brace - i ++ - break FOR - } else { - member += c - continue - } - - case ",": - if (depth === 1) { - addMember() - } else { - member += c - } - continue - - default: - member += c - continue - } // switch - } // else - } // for - - // now we've either finished the set, and the suffix is - // pattern.substr(i), or we have *not* closed the set, - // and need to escape the leading brace - if (depth !== 0) { - this.debug("didn't close", pattern) - return braceExpand.call(this, "\\" + pattern, options) - } - - // x{y,z} -> ["xy", "xz"] - this.debug("set", set) - this.debug("suffix", pattern.substr(i)) - var suf = braceExpand.call(this, pattern.substr(i), options) - // ["b", "c{d,e}","{f,g}h"] -> - // [["b"], ["cd", "ce"], ["fh", "gh"]] - var addBraces = set.length === 1 - this.debug("set pre-expanded", set) - set = set.map(function (p) { - return braceExpand.call(this, p, options) - }, this) - this.debug("set expanded", set) - - - // [["b"], ["cd", "ce"], ["fh", "gh"]] -> - // ["b", "cd", "ce", "fh", "gh"] - set = set.reduce(function (l, r) { - return l.concat(r) - }) - - if (addBraces) { - set = set.map(function (s) { - return "{" + s + "}" - }) - } - - // now attach the suffixes. - var ret = [] - for (var i = 0, l = set.length; i < l; i ++) { - for (var ii = 0, ll = suf.length; ii < ll; ii ++) { - ret.push(set[i] + suf[ii]) - } - } - return ret -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === "**") return GLOBSTAR - if (pattern === "") return "" - - var re = "" - , hasMagic = !!options.nocase - , escaping = false - // ? => one single character - , patternListStack = [] - , plType - , stateChar - , inClass = false - , reClassStart = -1 - , classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - , patternStart = pattern.charAt(0) === "." ? "" // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" - : "(?!\\.)" - , self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case "*": - re += star - hasMagic = true - break - case "?": - re += qmark - hasMagic = true - break - default: - re += "\\"+stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for ( var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i ++ ) { - - this.debug("%s\t%s %s %j", pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += "\\" + c - escaping = false - continue - } - - SWITCH: switch (c) { - case "/": - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case "\\": - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case "?": - case "*": - case "+": - case "@": - case "!": - this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === "!" && i === classStart + 1) c = "^" - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case "(": - if (inClass) { - re += "(" - continue - } - - if (!stateChar) { - re += "\\(" - continue - } - - plType = stateChar - patternListStack.push({ type: plType - , start: i - 1 - , reStart: re.length }) - // negation is (?:(?!js)[^/]*) - re += stateChar === "!" ? "(?:(?!" : "(?:" - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ")": - if (inClass || !patternListStack.length) { - re += "\\)" - continue - } - - clearStateChar() - hasMagic = true - re += ")" - plType = patternListStack.pop().type - // negation is (?:(?!js)[^/]*) - // The others are (?:) - switch (plType) { - case "!": - re += "[^/]*?)" - break - case "?": - case "+": - case "*": re += plType - case "@": break // the default anyway - } - continue - - case "|": - if (inClass || !patternListStack.length || escaping) { - re += "\\|" - escaping = false - continue - } - - clearStateChar() - re += "|" - continue - - // these are mostly the same in regexp and glob - case "[": - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += "\\" + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case "]": - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += "\\" + c - escaping = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === "^" && inClass)) { - re += "\\" - } - - re += c - - } // switch - } // for - - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - var cs = pattern.substr(classStart + 1) - , sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + "\\[" + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - var pl - while (pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + 3) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = "\\" - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + "|" - }) - - this.debug("tail=%j\n %s", tail, tail) - var t = pl.type === "*" ? star - : pl.type === "?" ? qmark - : "\\" + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) - + t + "\\(" - + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += "\\\\" - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case ".": - case "[": - case "(": addPatternStart = true - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== "" && hasMagic) re = "(?=.)" + re - - if (addPatternStart) re = patternStart + re - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [ re, hasMagic ] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? "i" : "" - , regExp = new RegExp("^" + re + "$", flags) - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) return this.regexp = false - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - , flags = options.nocase ? "i" : "" - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === "string") ? regExpEscape(p) - : p._src - }).join("\\\/") - }).join("|") - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = "^(?:" + re + ")$" - - // can match anything, as long as it's not this. - if (this.negate) re = "^(?!" + re + ").*$" - - try { - return this.regexp = new RegExp(re, flags) - } catch (ex) { - return this.regexp = false - } -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug("match", f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === "" - - if (f === "/" && partial) return true - - var options = this.options - - // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. - if (platform === "win32") { - f = f.split("\\").join("/") - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, "split", f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, "set", set) - - // Find the basename of the path by looking for the last non-empty segment - var filename; - for (var i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (var i = 0, l = set.length; i < l; i ++) { - var pattern = set[i], file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug("matchOne", - { "this": this - , file: file - , pattern: pattern }) - - this.debug("matchOne", file.length, pattern.length) - - for ( var fi = 0 - , pi = 0 - , fl = file.length - , pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi ++, pi ++ ) { - - this.debug("matchOne loop") - var p = pattern[pi] - , f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - , pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for ( ; fi < fl; fi ++) { - if (file[fi] === "." || file[fi] === ".." || - (!options.dot && file[fi].charAt(0) === ".")) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - WHILE: while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', - file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === "." || swallowee === ".." || - (!options.dot && swallowee.charAt(0) === ".")) { - this.debug("dot detected!", file, fr, pattern, pr) - break WHILE - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr ++ - } - } - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug("\n>>> no match, partial?", file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === "string") { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug("string match", p, f, hit) - } else { - hit = f.match(p) - this.debug("pattern match", p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === "") - return emptyFileEnd - } - - // should be unreachable. - throw new Error("wtf?") -} - - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, "$1") -} - - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") -} - -})( typeof require === "function" ? require : null, - this, - typeof module === "object" ? module : null, - typeof process === "object" ? process.platform : "win32" - ) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore deleted file mode 100644 index 07e6e472..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS deleted file mode 100644 index 4a0bc503..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +++ /dev/null @@ -1,14 +0,0 @@ -# Authors, sorted by whether or not they are me -Isaac Z. Schlueter -Brian Cottingham -Carlos Brito Lage -Jesse Dailey -Kevin O'Hara -Marco Rogers -Mark Cavage -Marko Mikulicic -Nathan Rajlich -Satheesh Natesan -Trent Mick -ashleybrener -n4kz diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE deleted file mode 100644 index 05a40109..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -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/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md deleted file mode 100644 index 03ee0f98..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# lru cache - -A cache object that deletes the least-recently-used items. - -## Usage: - -```javascript -var LRU = require("lru-cache") - , options = { max: 500 - , length: function (n) { return n * 2 } - , dispose: function (key, n) { n.close() } - , maxAge: 1000 * 60 * 60 } - , cache = LRU(options) - , otherCache = LRU(50) // sets just the max size - -cache.set("key", "value") -cache.get("key") // "value" - -cache.reset() // empty the cache -``` - -If you put more stuff in it, then items will fall out. - -If you try to put an oversized thing in it, then it'll fall out right -away. - -## Options - -* `max` The maximum size of the cache, checked by applying the length - function to all values in the cache. Not setting this is kind of - silly, since that's the whole purpose of this lib, but it defaults - to `Infinity`. -* `maxAge` Maximum age in ms. Items are not pro-actively pruned out - as they age, but if you try to get an item that is too old, it'll - drop it and return undefined instead of giving it to you. -* `length` Function that is used to calculate the length of stored - items. If you're storing strings or buffers, then you probably want - to do something like `function(n){return n.length}`. The default is - `function(n){return 1}`, which is fine if you want to store `n` - like-sized things. -* `dispose` Function that is called on items when they are dropped - from the cache. This can be handy if you want to close file - descriptors or do other cleanup tasks when items are no longer - accessible. Called with `key, value`. It's called *before* - actually removing the item from the internal cache, so if you want - to immediately put it back in, you'll have to do that in a - `nextTick` or `setTimeout` callback or it won't do anything. -* `stale` By default, if you set a `maxAge`, it'll only actually pull - stale items out of the cache when you `get(key)`. (That is, it's - not pre-emptively doing a `setTimeout` or anything.) If you set - `stale:true`, it'll return the stale value before deleting it. If - you don't set this, then it'll return `undefined` when you try to - get a stale entry, as if it had already been deleted. - -## API - -* `set(key, value)` -* `get(key) => value` - - Both of these will update the "recently used"-ness of the key. - They do what you think. - -* `peek(key)` - - Returns the key value (or `undefined` if not found) without - updating the "recently used"-ness of the key. - - (If you find yourself using this a lot, you *might* be using the - wrong sort of data structure, but there are some use cases where - it's handy.) - -* `del(key)` - - Deletes a key out of the cache. - -* `reset()` - - Clear the cache entirely, throwing away all values. - -* `has(key)` - - Check if a key is in the cache, without updating the recent-ness - or deleting it for being stale. - -* `forEach(function(value,key,cache), [thisp])` - - Just like `Array.prototype.forEach`. Iterates over all the keys - in the cache, in order of recent-ness. (Ie, more recently used - items are iterated over first.) - -* `keys()` - - Return an array of the keys in the cache. - -* `values()` - - Return an array of the values in the cache. diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js deleted file mode 100644 index d1d13817..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +++ /dev/null @@ -1,252 +0,0 @@ -;(function () { // closure for web browsers - -if (typeof module === 'object' && module.exports) { - module.exports = LRUCache -} else { - // just set the global for non-node platforms. - this.LRUCache = LRUCache -} - -function hOP (obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key) -} - -function naiveLength () { return 1 } - -function LRUCache (options) { - if (!(this instanceof LRUCache)) - return new LRUCache(options) - - if (typeof options === 'number') - options = { max: options } - - if (!options) - options = {} - - this._max = options.max - // Kind of weird to have a default max of Infinity, but oh well. - if (!this._max || !(typeof this._max === "number") || this._max <= 0 ) - this._max = Infinity - - this._lengthCalculator = options.length || naiveLength - if (typeof this._lengthCalculator !== "function") - this._lengthCalculator = naiveLength - - this._allowStale = options.stale || false - this._maxAge = options.maxAge || null - this._dispose = options.dispose - this.reset() -} - -// resize the cache when the max changes. -Object.defineProperty(LRUCache.prototype, "max", - { set : function (mL) { - if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity - this._max = mL - if (this._length > this._max) trim(this) - } - , get : function () { return this._max } - , enumerable : true - }) - -// resize the cache when the lengthCalculator changes. -Object.defineProperty(LRUCache.prototype, "lengthCalculator", - { set : function (lC) { - if (typeof lC !== "function") { - this._lengthCalculator = naiveLength - this._length = this._itemCount - for (var key in this._cache) { - this._cache[key].length = 1 - } - } else { - this._lengthCalculator = lC - this._length = 0 - for (var key in this._cache) { - this._cache[key].length = this._lengthCalculator(this._cache[key].value) - this._length += this._cache[key].length - } - } - - if (this._length > this._max) trim(this) - } - , get : function () { return this._lengthCalculator } - , enumerable : true - }) - -Object.defineProperty(LRUCache.prototype, "length", - { get : function () { return this._length } - , enumerable : true - }) - - -Object.defineProperty(LRUCache.prototype, "itemCount", - { get : function () { return this._itemCount } - , enumerable : true - }) - -LRUCache.prototype.forEach = function (fn, thisp) { - thisp = thisp || this - var i = 0; - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - i++ - var hit = this._lruList[k] - if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { - del(this, hit) - if (!this._allowStale) hit = undefined - } - if (hit) { - fn.call(thisp, hit.value, hit.key, this) - } - } -} - -LRUCache.prototype.keys = function () { - var keys = new Array(this._itemCount) - var i = 0 - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - var hit = this._lruList[k] - keys[i++] = hit.key - } - return keys -} - -LRUCache.prototype.values = function () { - var values = new Array(this._itemCount) - var i = 0 - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - var hit = this._lruList[k] - values[i++] = hit.value - } - return values -} - -LRUCache.prototype.reset = function () { - if (this._dispose && this._cache) { - for (var k in this._cache) { - this._dispose(k, this._cache[k].value) - } - } - - this._cache = Object.create(null) // hash of items by key - this._lruList = Object.create(null) // list of items in order of use recency - this._mru = 0 // most recently used - this._lru = 0 // least recently used - this._length = 0 // number of items in the list - this._itemCount = 0 -} - -// Provided for debugging/dev purposes only. No promises whatsoever that -// this API stays stable. -LRUCache.prototype.dump = function () { - return this._cache -} - -LRUCache.prototype.dumpLru = function () { - return this._lruList -} - -LRUCache.prototype.set = function (key, value) { - if (hOP(this._cache, key)) { - // dispose of the old one before overwriting - if (this._dispose) this._dispose(key, this._cache[key].value) - if (this._maxAge) this._cache[key].now = Date.now() - this._cache[key].value = value - this.get(key) - return true - } - - var len = this._lengthCalculator(value) - var age = this._maxAge ? Date.now() : 0 - var hit = new Entry(key, value, this._mru++, len, age) - - // oversized objects fall out of cache automatically. - if (hit.length > this._max) { - if (this._dispose) this._dispose(key, value) - return false - } - - this._length += hit.length - this._lruList[hit.lu] = this._cache[key] = hit - this._itemCount ++ - - if (this._length > this._max) trim(this) - return true -} - -LRUCache.prototype.has = function (key) { - if (!hOP(this._cache, key)) return false - var hit = this._cache[key] - if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { - return false - } - return true -} - -LRUCache.prototype.get = function (key) { - return get(this, key, true) -} - -LRUCache.prototype.peek = function (key) { - return get(this, key, false) -} - -LRUCache.prototype.pop = function () { - var hit = this._lruList[this._lru] - del(this, hit) - return hit || null -} - -LRUCache.prototype.del = function (key) { - del(this, this._cache[key]) -} - -function get (self, key, doUse) { - var hit = self._cache[key] - if (hit) { - if (self._maxAge && (Date.now() - hit.now > self._maxAge)) { - del(self, hit) - if (!self._allowStale) hit = undefined - } else { - if (doUse) use(self, hit) - } - if (hit) hit = hit.value - } - return hit -} - -function use (self, hit) { - shiftLU(self, hit) - hit.lu = self._mru ++ - self._lruList[hit.lu] = hit -} - -function trim (self) { - while (self._lru < self._mru && self._length > self._max) - del(self, self._lruList[self._lru]) -} - -function shiftLU (self, hit) { - delete self._lruList[ hit.lu ] - while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++ -} - -function del (self, hit) { - if (hit) { - if (self._dispose) self._dispose(hit.key, hit.value) - self._length -= hit.length - self._itemCount -- - delete self._cache[ hit.key ] - shiftLU(self, hit) - } -} - -// classy, since V8 prefers predictable objects. -function Entry (key, value, lu, length, now) { - this.key = key - this.value = value - this.lu = lu - this.length = length - this.now = now -} - -})() diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json deleted file mode 100644 index 2474729b..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "lru-cache", - "description": "A cache object that deletes the least-recently-used items.", - "version": "2.5.0", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "scripts": { - "test": "tap test --gc" - }, - "main": "lib/lru-cache.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-lru-cache.git" - }, - "devDependencies": { - "tap": "", - "weak": "" - }, - "license": { - "type": "MIT", - "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/node-lru-cache/issues" - }, - "homepage": "https://github.com/isaacs/node-lru-cache", - "_id": "lru-cache@2.5.0", - "dist": { - "shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb", - "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz" - }, - "_from": "lru-cache@2", - "_npmVersion": "1.3.15", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb", - "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js deleted file mode 100644 index f72697c4..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js +++ /dev/null @@ -1,369 +0,0 @@ -var test = require("tap").test - , LRU = require("../") - -test("basic", function (t) { - var cache = new LRU({max: 10}) - cache.set("key", "value") - t.equal(cache.get("key"), "value") - t.equal(cache.get("nada"), undefined) - t.equal(cache.length, 1) - t.equal(cache.max, 10) - t.end() -}) - -test("least recently set", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), "B") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("lru recently gotten", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - cache.get("a") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), undefined) - t.equal(cache.get("a"), "A") - t.end() -}) - -test("del", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.del("a") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("max", function (t) { - var cache = new LRU(3) - - // test changing the max, verify that the LRU items get dropped. - cache.max = 100 - for (var i = 0; i < 100; i ++) cache.set(i, i) - t.equal(cache.length, 100) - for (var i = 0; i < 100; i ++) { - t.equal(cache.get(i), i) - } - cache.max = 3 - t.equal(cache.length, 3) - for (var i = 0; i < 97; i ++) { - t.equal(cache.get(i), undefined) - } - for (var i = 98; i < 100; i ++) { - t.equal(cache.get(i), i) - } - - // now remove the max restriction, and try again. - cache.max = "hello" - for (var i = 0; i < 100; i ++) cache.set(i, i) - t.equal(cache.length, 100) - for (var i = 0; i < 100; i ++) { - t.equal(cache.get(i), i) - } - // should trigger an immediate resize - cache.max = 3 - t.equal(cache.length, 3) - for (var i = 0; i < 97; i ++) { - t.equal(cache.get(i), undefined) - } - for (var i = 98; i < 100; i ++) { - t.equal(cache.get(i), i) - } - t.end() -}) - -test("reset", function (t) { - var cache = new LRU(10) - cache.set("a", "A") - cache.set("b", "B") - cache.reset() - t.equal(cache.length, 0) - t.equal(cache.max, 10) - t.equal(cache.get("a"), undefined) - t.equal(cache.get("b"), undefined) - t.end() -}) - - -// Note: `.dump()` is a debugging tool only. No guarantees are made -// about the format/layout of the response. -test("dump", function (t) { - var cache = new LRU(10) - var d = cache.dump(); - t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache") - cache.set("a", "A") - var d = cache.dump() // { a: { key: "a", value: "A", lu: 0 } } - t.ok(d.a) - t.equal(d.a.key, "a") - t.equal(d.a.value, "A") - t.equal(d.a.lu, 0) - - cache.set("b", "B") - cache.get("b") - d = cache.dump() - t.ok(d.b) - t.equal(d.b.key, "b") - t.equal(d.b.value, "B") - t.equal(d.b.lu, 2) - - t.end() -}) - - -test("basic with weighed length", function (t) { - var cache = new LRU({ - max: 100, - length: function (item) { return item.size } - }) - cache.set("key", {val: "value", size: 50}) - t.equal(cache.get("key").val, "value") - t.equal(cache.get("nada"), undefined) - t.equal(cache.lengthCalculator(cache.get("key")), 50) - t.equal(cache.length, 50) - t.equal(cache.max, 100) - t.end() -}) - - -test("weighed length item too large", function (t) { - var cache = new LRU({ - max: 10, - length: function (item) { return item.size } - }) - t.equal(cache.max, 10) - - // should fall out immediately - cache.set("key", {val: "value", size: 50}) - - t.equal(cache.length, 0) - t.equal(cache.get("key"), undefined) - t.end() -}) - -test("least recently set with weighed length", function (t) { - var cache = new LRU({ - max:8, - length: function (item) { return item.length } - }) - cache.set("a", "A") - cache.set("b", "BB") - cache.set("c", "CCC") - cache.set("d", "DDDD") - t.equal(cache.get("d"), "DDDD") - t.equal(cache.get("c"), "CCC") - t.equal(cache.get("b"), undefined) - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("lru recently gotten with weighed length", function (t) { - var cache = new LRU({ - max: 8, - length: function (item) { return item.length } - }) - cache.set("a", "A") - cache.set("b", "BB") - cache.set("c", "CCC") - cache.get("a") - cache.get("b") - cache.set("d", "DDDD") - t.equal(cache.get("c"), undefined) - t.equal(cache.get("d"), "DDDD") - t.equal(cache.get("b"), "BB") - t.equal(cache.get("a"), "A") - t.end() -}) - -test("set returns proper booleans", function(t) { - var cache = new LRU({ - max: 5, - length: function (item) { return item.length } - }) - - t.equal(cache.set("a", "A"), true) - - // should return false for max exceeded - t.equal(cache.set("b", "donuts"), false) - - t.equal(cache.set("b", "B"), true) - t.equal(cache.set("c", "CCCC"), true) - t.end() -}) - -test("drop the old items", function(t) { - var cache = new LRU({ - max: 5, - maxAge: 50 - }) - - cache.set("a", "A") - - setTimeout(function () { - cache.set("b", "b") - t.equal(cache.get("a"), "A") - }, 25) - - setTimeout(function () { - cache.set("c", "C") - // timed out - t.notOk(cache.get("a")) - }, 60) - - setTimeout(function () { - t.notOk(cache.get("b")) - t.equal(cache.get("c"), "C") - }, 90) - - setTimeout(function () { - t.notOk(cache.get("c")) - t.end() - }, 155) -}) - -test("disposal function", function(t) { - var disposed = false - var cache = new LRU({ - max: 1, - dispose: function (k, n) { - disposed = n - } - }) - - cache.set(1, 1) - cache.set(2, 2) - t.equal(disposed, 1) - cache.set(3, 3) - t.equal(disposed, 2) - cache.reset() - t.equal(disposed, 3) - t.end() -}) - -test("disposal function on too big of item", function(t) { - var disposed = false - var cache = new LRU({ - max: 1, - length: function (k) { - return k.length - }, - dispose: function (k, n) { - disposed = n - } - }) - var obj = [ 1, 2 ] - - t.equal(disposed, false) - cache.set("obj", obj) - t.equal(disposed, obj) - t.end() -}) - -test("has()", function(t) { - var cache = new LRU({ - max: 1, - maxAge: 10 - }) - - cache.set('foo', 'bar') - t.equal(cache.has('foo'), true) - cache.set('blu', 'baz') - t.equal(cache.has('foo'), false) - t.equal(cache.has('blu'), true) - setTimeout(function() { - t.equal(cache.has('blu'), false) - t.end() - }, 15) -}) - -test("stale", function(t) { - var cache = new LRU({ - maxAge: 10, - stale: true - }) - - cache.set('foo', 'bar') - t.equal(cache.get('foo'), 'bar') - t.equal(cache.has('foo'), true) - setTimeout(function() { - t.equal(cache.has('foo'), false) - t.equal(cache.get('foo'), 'bar') - t.equal(cache.get('foo'), undefined) - t.end() - }, 15) -}) - -test("lru update via set", function(t) { - var cache = LRU({ max: 2 }); - - cache.set('foo', 1); - cache.set('bar', 2); - cache.del('bar'); - cache.set('baz', 3); - cache.set('qux', 4); - - t.equal(cache.get('foo'), undefined) - t.equal(cache.get('bar'), undefined) - t.equal(cache.get('baz'), 3) - t.equal(cache.get('qux'), 4) - t.end() -}) - -test("least recently set w/ peek", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - t.equal(cache.peek("a"), "A") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), "B") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("pop the least used item", function (t) { - var cache = new LRU(3) - , last - - cache.set("a", "A") - cache.set("b", "B") - cache.set("c", "C") - - t.equal(cache.length, 3) - t.equal(cache.max, 3) - - // Ensure we pop a, c, b - cache.get("b", "B") - - last = cache.pop() - t.equal(last.key, "a") - t.equal(last.value, "A") - t.equal(cache.length, 2) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last.key, "c") - t.equal(last.value, "C") - t.equal(cache.length, 1) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last.key, "b") - t.equal(last.value, "B") - t.equal(cache.length, 0) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last, null) - t.equal(cache.length, 0) - t.equal(cache.max, 3) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js deleted file mode 100644 index eefb80d9..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +++ /dev/null @@ -1,52 +0,0 @@ -var test = require('tap').test -var LRU = require('../') - -test('forEach', function (t) { - var l = new LRU(5) - for (var i = 0; i < 10; i ++) { - l.set(i.toString(), i.toString(2)) - } - - var i = 9 - l.forEach(function (val, key, cache) { - t.equal(cache, l) - t.equal(key, i.toString()) - t.equal(val, i.toString(2)) - i -= 1 - }) - - // get in order of most recently used - l.get(6) - l.get(8) - - var order = [ 8, 6, 9, 7, 5 ] - var i = 0 - - l.forEach(function (val, key, cache) { - var j = order[i ++] - t.equal(cache, l) - t.equal(key, j.toString()) - t.equal(val, j.toString(2)) - }) - - t.end() -}) - -test('keys() and values()', function (t) { - var l = new LRU(5) - for (var i = 0; i < 10; i ++) { - l.set(i.toString(), i.toString(2)) - } - - t.similar(l.keys(), ['9', '8', '7', '6', '5']) - t.similar(l.values(), ['1001', '1000', '111', '110', '101']) - - // get in order of most recently used - l.get(6) - l.get(8) - - t.similar(l.keys(), ['8', '6', '9', '7', '5']) - t.similar(l.values(), ['1000', '110', '1001', '111', '101']) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js deleted file mode 100644 index 7af45b02..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node --expose_gc - -var weak = require('weak'); -var test = require('tap').test -var LRU = require('../') -var l = new LRU({ max: 10 }) -var refs = 0 -function X() { - refs ++ - weak(this, deref) -} - -function deref() { - refs -- -} - -test('no leaks', function (t) { - // fill up the cache - for (var i = 0; i < 100; i++) { - l.set(i, new X); - // throw some gets in there, too. - if (i % 2 === 0) - l.get(i / 2) - } - - gc() - - var start = process.memoryUsage() - - // capture the memory - var startRefs = refs - - // do it again, but more - for (var i = 0; i < 10000; i++) { - l.set(i, new X); - // throw some gets in there, too. - if (i % 2 === 0) - l.get(i / 2) - } - - gc() - - var end = process.memoryUsage() - t.equal(refs, startRefs, 'no leaky refs') - - console.error('start: %j\n' + - 'end: %j', start, end); - t.pass(); - t.end(); -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE deleted file mode 100644 index 0c44ae71..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) Isaac Z. Schlueter ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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 AUTHOR 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 AUTHOR 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/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md deleted file mode 100644 index 7e365129..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# sigmund - -Quick and dirty signatures for Objects. - -This is like a much faster `deepEquals` comparison, which returns a -string key suitable for caches and the like. - -## Usage - -```javascript -function doSomething (someObj) { - var key = sigmund(someObj, maxDepth) // max depth defaults to 10 - var cached = cache.get(key) - if (cached) return cached) - - var result = expensiveCalculation(someObj) - cache.set(key, result) - return result -} -``` - -The resulting key will be as unique and reproducible as calling -`JSON.stringify` or `util.inspect` on the object, but is much faster. -In order to achieve this speed, some differences are glossed over. -For example, the object `{0:'foo'}` will be treated identically to the -array `['foo']`. - -Also, just as there is no way to summon the soul from the scribblings -of a cocain-addled psychoanalyst, there is no way to revive the object -from the signature string that sigmund gives you. In fact, it's -barely even readable. - -As with `sys.inspect` and `JSON.stringify`, larger objects will -produce larger signature strings. - -Because sigmund is a bit less strict than the more thorough -alternatives, the strings will be shorter, and also there is a -slightly higher chance for collisions. For example, these objects -have the same signature: - - var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} - var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} - -Like a good Freudian, sigmund is most effective when you already have -some understanding of what you're looking for. It can help you help -yourself, but you must be willing to do some work as well. - -Cycles are handled, and cyclical objects are silently omitted (though -the key is included in the signature output.) - -The second argument is the maximum depth, which defaults to 10, -because that is the maximum object traversal depth covered by most -insurance carriers. diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js deleted file mode 100644 index 5acfd6d9..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js +++ /dev/null @@ -1,283 +0,0 @@ -// different ways to id objects -// use a req/res pair, since it's crazy deep and cyclical - -// sparseFE10 and sigmund are usually pretty close, which is to be expected, -// since they are essentially the same algorithm, except that sigmund handles -// regular expression objects properly. - - -var http = require('http') -var util = require('util') -var sigmund = require('./sigmund.js') -var sreq, sres, creq, cres, test - -http.createServer(function (q, s) { - sreq = q - sres = s - sres.end('ok') - this.close(function () { setTimeout(function () { - start() - }, 200) }) -}).listen(1337, function () { - creq = http.get({ port: 1337 }) - creq.on('response', function (s) { cres = s }) -}) - -function start () { - test = [sreq, sres, creq, cres] - // test = sreq - // sreq.sres = sres - // sreq.creq = creq - // sreq.cres = cres - - for (var i in exports.compare) { - console.log(i) - var hash = exports.compare[i]() - console.log(hash) - console.log(hash.length) - console.log('') - } - - require('bench').runMain() -} - -function customWs (obj, md, d) { - d = d || 0 - var to = typeof obj - if (to === 'undefined' || to === 'function' || to === null) return '' - if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '') - - if (Array.isArray(obj)) { - return obj.map(function (i, _, __) { - return customWs(i, md, d + 1) - }).reduce(function (a, b) { return a + b }, '') - } - - var keys = Object.keys(obj) - return keys.map(function (k, _, __) { - return k + ':' + customWs(obj[k], md, d + 1) - }).reduce(function (a, b) { return a + b }, '') -} - -function custom (obj, md, d) { - d = d || 0 - var to = typeof obj - if (to === 'undefined' || to === 'function' || to === null) return '' - if (d > md || !obj || to !== 'object') return '' + obj - - if (Array.isArray(obj)) { - return obj.map(function (i, _, __) { - return custom(i, md, d + 1) - }).reduce(function (a, b) { return a + b }, '') - } - - var keys = Object.keys(obj) - return keys.map(function (k, _, __) { - return k + ':' + custom(obj[k], md, d + 1) - }).reduce(function (a, b) { return a + b }, '') -} - -function sparseFE2 (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - Object.keys(v).forEach(function (k, _, __) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') return - var to = typeof v[k] - if (to === 'function' || to === 'undefined') return - soFar += k + ':' - ch(v[k], depth + 1) - }) - soFar += '}' - } - ch(obj, 0) - return soFar -} - -function sparseFE (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - Object.keys(v).forEach(function (k, _, __) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') return - var to = typeof v[k] - if (to === 'function' || to === 'undefined') return - soFar += k - ch(v[k], depth + 1) - }) - } - ch(obj, 0) - return soFar -} - -function sparse (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k - ch(v[k], depth + 1) - } - } - ch(obj, 0) - return soFar -} - -function noCommas (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k + ':' - ch(v[k], depth + 1) - } - soFar += '}' - } - ch(obj, 0) - return soFar -} - - -function flatten (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k + ':' - ch(v[k], depth + 1) - soFar += ',' - } - soFar += '}' - } - ch(obj, 0) - return soFar -} - -exports.compare = -{ - // 'custom 2': function () { - // return custom(test, 2, 0) - // }, - // 'customWs 2': function () { - // return customWs(test, 2, 0) - // }, - 'JSON.stringify (guarded)': function () { - var seen = [] - return JSON.stringify(test, function (k, v) { - if (typeof v !== 'object' || !v) return v - if (seen.indexOf(v) !== -1) return undefined - seen.push(v) - return v - }) - }, - - 'flatten 10': function () { - return flatten(test, 10) - }, - - // 'flattenFE 10': function () { - // return flattenFE(test, 10) - // }, - - 'noCommas 10': function () { - return noCommas(test, 10) - }, - - 'sparse 10': function () { - return sparse(test, 10) - }, - - 'sparseFE 10': function () { - return sparseFE(test, 10) - }, - - 'sparseFE2 10': function () { - return sparseFE2(test, 10) - }, - - sigmund: function() { - return sigmund(test, 10) - }, - - - // 'util.inspect 1': function () { - // return util.inspect(test, false, 1, false) - // }, - // 'util.inspect undefined': function () { - // util.inspect(test) - // }, - // 'util.inspect 2': function () { - // util.inspect(test, false, 2, false) - // }, - // 'util.inspect 3': function () { - // util.inspect(test, false, 3, false) - // }, - // 'util.inspect 4': function () { - // util.inspect(test, false, 4, false) - // }, - // 'util.inspect Infinity': function () { - // util.inspect(test, false, Infinity, false) - // } -} - -/** results -**/ diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json deleted file mode 100644 index a1f755a7..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "sigmund", - "version": "1.0.0", - "description": "Quick and dirty signatures for Objects.", - "main": "sigmund.js", - "directories": { - "test": "test" - }, - "dependencies": {}, - "devDependencies": { - "tap": "~0.3.0" - }, - "scripts": { - "test": "tap test/*.js", - "bench": "node bench.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/sigmund" - }, - "keywords": [ - "object", - "signature", - "key", - "data", - "psychoanalysis" - ], - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "license": "BSD", - "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n var cached = cache.get(key)\n if (cached) return cached)\n\n var result = expensiveCalculation(someObj)\n cache.set(key, result)\n return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you. In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions. For example, these objects\nhave the same signature:\n\n var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for. It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n", - "_id": "sigmund@1.0.0", - "dist": { - "shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296", - "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz" - }, - "_npmVersion": "1.1.48", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296", - "_from": "sigmund@~1.0.0", - "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz", - "bugs": { - "url": "https://github.com/isaacs/sigmund/issues" - }, - "homepage": "https://github.com/isaacs/sigmund" -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js deleted file mode 100644 index 82c7ab8c..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = sigmund -function sigmund (subject, maxSessions) { - maxSessions = maxSessions || 10; - var notes = []; - var analysis = ''; - var RE = RegExp; - - function psychoAnalyze (subject, session) { - if (session > maxSessions) return; - - if (typeof subject === 'function' || - typeof subject === 'undefined') { - return; - } - - if (typeof subject !== 'object' || !subject || - (subject instanceof RE)) { - analysis += subject; - return; - } - - if (notes.indexOf(subject) !== -1 || session === maxSessions) return; - - notes.push(subject); - analysis += '{'; - Object.keys(subject).forEach(function (issue, _, __) { - // pseudo-private values. skip those. - if (issue.charAt(0) === '_') return; - var to = typeof subject[issue]; - if (to === 'function' || to === 'undefined') return; - analysis += issue; - psychoAnalyze(subject[issue], session + 1); - }); - } - psychoAnalyze(subject, 0); - return analysis; -} - -// vim: set softtabstop=4 shiftwidth=4: diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js deleted file mode 100644 index 50c53a13..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js +++ /dev/null @@ -1,24 +0,0 @@ -var test = require('tap').test -var sigmund = require('../sigmund.js') - - -// occasionally there are duplicates -// that's an acceptable edge-case. JSON.stringify and util.inspect -// have some collision potential as well, though less, and collision -// detection is expensive. -var hash = '{abc/def/g{0h1i2{jkl' -var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} -var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} - -var obj3 = JSON.parse(JSON.stringify(obj1)) -obj3.c = /def/ -obj3.g[2].cycle = obj3 -var cycleHash = '{abc/def/g{0h1i2{jklcycle' - -test('basic', function (t) { - t.equal(sigmund(obj1), hash) - t.equal(sigmund(obj2), hash) - t.equal(sigmund(obj3), cycleHash) - t.end() -}) - diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json deleted file mode 100644 index 0fe147d6..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me" - }, - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "0.3.0", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "minimatch.js", - "scripts": { - "test": "tap test/*.js" - }, - "engines": { - "node": "*" - }, - "dependencies": { - "lru-cache": "2", - "sigmund": "~1.0.0" - }, - "devDependencies": { - "tap": "" - }, - "license": { - "type": "MIT", - "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/minimatch/issues" - }, - "homepage": "https://github.com/isaacs/minimatch", - "_id": "minimatch@0.3.0", - "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", - "_from": "minimatch@0.3", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", - "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js deleted file mode 100644 index ae7ac73c..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js +++ /dev/null @@ -1,399 +0,0 @@ -// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test -// -// TODO: Some of these tests do very bad things with backslashes, and will -// most likely fail badly on windows. They should probably be skipped. - -var tap = require("tap") - , globalBefore = Object.keys(global) - , mm = require("../") - , files = [ "a", "b", "c", "d", "abc" - , "abd", "abe", "bb", "bcd" - , "ca", "cb", "dd", "de" - , "bdir/", "bdir/cfile"] - , next = files.concat([ "a-b", "aXb" - , ".x", ".y" ]) - - -var patterns = - [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test" - , ["a*", ["a", "abc", "abd", "abe"]] - , ["X*", ["X*"], {nonull: true}] - - // allow null glob expansion - , ["X*", []] - - // isaacs: Slightly different than bash/sh/ksh - // \\* is not un-escaped to literal "*" in a failed match, - // but it does make it get treated as a literal star - , ["\\*", ["\\*"], {nonull: true}] - , ["\\**", ["\\**"], {nonull: true}] - , ["\\*\\*", ["\\*\\*"], {nonull: true}] - - , ["b*/", ["bdir/"]] - , ["c*", ["c", "ca", "cb"]] - , ["**", files] - - , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] - , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] - - , "legendary larry crashes bashes" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] - - , "character classes" - , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] - , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", - "bdir/", "ca", "cb", "dd", "de"]] - , ["a*[^c]", ["abd", "abe"]] - , function () { files.push("a-b", "aXb") } - , ["a[X-]b", ["a-b", "aXb"]] - , function () { files.push(".x", ".y") } - , ["[^a-c]*", ["d", "dd", "de"]] - , function () { files.push("a*b/", "a*b/ooo") } - , ["a\\*b/*", ["a*b/ooo"]] - , ["a\\*?/*", ["a*b/ooo"]] - , ["*\\\\!*", [], {null: true}, ["echo !7"]] - , ["*\\!*", ["echo !7"], null, ["echo !7"]] - , ["*.\\*", ["r.*"], null, ["r.*"]] - , ["a[b]c", ["abc"]] - , ["a[\\b]c", ["abc"]] - , ["a?c", ["abc"]] - , ["a\\*c", [], {null: true}, ["abc"]] - , ["", [""], { null: true }, [""]] - - , "http://www.opensource.apple.com/source/bash/bash-23/" + - "bash/tests/glob-test" - , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } - , ["*/man*/bash.*", ["man/man1/bash.1"]] - , ["man/man1/bash.1", ["man/man1/bash.1"]] - , ["a***c", ["abc"], null, ["abc"]] - , ["a*****?c", ["abc"], null, ["abc"]] - , ["?*****??", ["abc"], null, ["abc"]] - , ["*****??", ["abc"], null, ["abc"]] - , ["?*****?c", ["abc"], null, ["abc"]] - , ["?***?****c", ["abc"], null, ["abc"]] - , ["?***?****?", ["abc"], null, ["abc"]] - , ["?***?****", ["abc"], null, ["abc"]] - , ["*******c", ["abc"], null, ["abc"]] - , ["*******?", ["abc"], null, ["abc"]] - , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["[-abc]", ["-"], null, ["-"]] - , ["[abc-]", ["-"], null, ["-"]] - , ["\\", ["\\"], null, ["\\"]] - , ["[\\\\]", ["\\"], null, ["\\"]] - , ["[[]", ["["], null, ["["]] - , ["[", ["["], null, ["["]] - , ["[*", ["[abc"], null, ["[abc"]] - , "a right bracket shall lose its special meaning and\n" + - "represent itself in a bracket expression if it occurs\n" + - "first in the list. -- POSIX.2 2.8.3.2" - , ["[]]", ["]"], null, ["]"]] - , ["[]-]", ["]"], null, ["]"]] - , ["[a-\z]", ["p"], null, ["p"]] - , ["??**********?****?", [], { null: true }, ["abc"]] - , ["??**********?****c", [], { null: true }, ["abc"]] - , ["?************c****?****", [], { null: true }, ["abc"]] - , ["*c*?**", [], { null: true }, ["abc"]] - , ["a*****c*?**", [], { null: true }, ["abc"]] - , ["a********???*******", [], { null: true }, ["abc"]] - , ["[]", [], { null: true }, ["a"]] - , ["[abc", [], { null: true }, ["["]] - - , "nocase tests" - , ["XYZ", ["xYz"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["ab*", ["ABC"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - - // [ pattern, [matches], MM opts, files, TAP opts] - , "onestar/twostar" - , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] - , ["{/?,*}", ["/a", "bb"], {null: true} - , ["/a", "/b/b", "/a/b/c", "bb"]] - - , "dots should not match unless requested" - , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] - - // .. and . can only match patterns starting with ., - // even when options.dot is set. - , function () { - files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] - } - , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] - , ["a/*/b", ["a/c/b"], {dot:false}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] - - - // this also tests that changing the options needs - // to change the cache key, even if the pattern is - // the same! - , ["**", ["a/b","a/.d",".a/.d"], { dot: true } - , [ ".a/.d", "a/.d", "a/b"]] - - , "paren sets cannot contain slashes" - , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] - - // brace sets trump all else. - // - // invalid glob pattern. fails on bash4 and bsdglob. - // however, in this implementation, it's easier just - // to do the intuitive thing, and let brace-expansion - // actually come before parsing any extglob patterns, - // like the documentation seems to say. - // - // XXX: if anyone complains about this, either fix it - // or tell them to grow up and stop complaining. - // - // bash/bsdglob says this: - // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] - // but we do this instead: - , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] - - // test partial parsing in the presence of comment/negation chars - , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] - , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] - - // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. - , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] - , {} - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] - - - // crazy nested {,,} and *(||) tests. - , function () { - files = [ "a", "b", "c", "d" - , "ab", "ac", "ad" - , "bc", "cb" - , "bc,d", "c,db", "c,d" - , "d)", "(b|c", "*(b|c" - , "b|c", "b|cc", "cb|c" - , "x(a|b|c)", "x(a|c)" - , "(a|b|c)", "(a|c)"] - } - , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] - , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] - // a - // *(b|c) - // *(b|d) - , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] - , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] - - - // test various flag settings. - , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] - , { noext: true } ] - , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} - , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] - , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] - - - // begin channelling Boole and deMorgan... - , "negation tests" - , function () { - files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] - } - - // anything that is NOT a* matches. - , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] - - // anything that IS !a* matches. - , ["!a*", ["!ab", "!abc"], {nonegate: true}] - - // anything that IS a* matches - , ["!!a*", ["a!b"]] - - // anything that is NOT !a* matches - , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] - - // negation nestled within a pattern - , function () { - files = [ "foo.js" - , "foo.bar" - // can't match this one without negative lookbehind. - , "foo.js.js" - , "blar.js" - , "foo." - , "boo.js.boo" ] - } - , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] - - // https://github.com/isaacs/minimatch/issues/5 - , function () { - files = [ 'a/b/.x/c' - , 'a/b/.x/c/d' - , 'a/b/.x/c/d/e' - , 'a/b/.x' - , 'a/b/.x/' - , 'a/.x/b' - , '.x' - , '.x/' - , '.x/a' - , '.x/a/b' - , 'a/.x/b/.x/c' - , '.x/.x' ] - } - , ["**/.x/**", [ '.x/' - , '.x/a' - , '.x/a/b' - , 'a/.x/b' - , 'a/b/.x/' - , 'a/b/.x/c' - , 'a/b/.x/c/d' - , 'a/b/.x/c/d/e' ] ] - - ] - -var regexps = - [ '/^(?:(?=.)a[^/]*?)$/', - '/^(?:(?=.)X[^/]*?)$/', - '/^(?:(?=.)X[^/]*?)$/', - '/^(?:\\*)$/', - '/^(?:(?=.)\\*[^/]*?)$/', - '/^(?:\\*\\*)$/', - '/^(?:(?=.)b[^/]*?\\/)$/', - '/^(?:(?=.)c[^/]*?)$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', - '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/', - '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/', - '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/', - '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/', - '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/', - '/^(?:(?=.)a[^/]*?[^c])$/', - '/^(?:(?=.)a[X-]b)$/', - '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/', - '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/', - '/^(?:(?=.)a[b]c)$/', - '/^(?:(?=.)a[b]c)$/', - '/^(?:(?=.)a[^/]c)$/', - '/^(?:a\\*c)$/', - 'false', - '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/', - '/^(?:man\\/man1\\/bash\\.1)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[-abc])$/', - '/^(?:(?!\\.)(?=.)[abc-])$/', - '/^(?:\\\\)$/', - '/^(?:(?!\\.)(?=.)[\\\\])$/', - '/^(?:(?!\\.)(?=.)[\\[])$/', - '/^(?:\\[)$/', - '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[\\]])$/', - '/^(?:(?!\\.)(?=.)[\\]-])$/', - '/^(?:(?!\\.)(?=.)[a-z])$/', - '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:\\[\\])$/', - '/^(?:\\[abc)$/', - '/^(?:(?=.)XYZ)$/i', - '/^(?:(?=.)ab[^/]*?)$/i', - '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i', - '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/', - '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', - '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/', - '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', - '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/', - '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', - '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/', - '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/', - '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/', - '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/', - '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/', - '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/', - '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/', - '/^(?:(?=.)a[^/]b)$/', - '/^(?:(?=.)#[^/]*?)$/', - '/^(?!^(?:(?=.)a[^/]*?)$).*$/', - '/^(?:(?=.)\\!a[^/]*?)$/', - '/^(?:(?=.)a[^/]*?)$/', - '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ] -var re = 0; - -tap.test("basic tests", function (t) { - var start = Date.now() - - // [ pattern, [matches], MM opts, files, TAP opts] - patterns.forEach(function (c) { - if (typeof c === "function") return c() - if (typeof c === "string") return t.comment(c) - - var pattern = c[0] - , expect = c[1].sort(alpha) - , options = c[2] || {} - , f = c[3] || files - , tapOpts = c[4] || {} - - // options.debug = true - var m = new mm.Minimatch(pattern, options) - var r = m.makeRe() - var expectRe = regexps[re++] - tapOpts.re = String(r) || JSON.stringify(r) - tapOpts.files = JSON.stringify(f) - tapOpts.pattern = pattern - tapOpts.set = m.set - tapOpts.negated = m.negate - - var actual = mm.match(f, pattern, options) - actual.sort(alpha) - - t.equivalent( actual, expect - , JSON.stringify(pattern) + " " + JSON.stringify(expect) - , tapOpts ) - - t.equal(tapOpts.re, expectRe, tapOpts) - }) - - t.comment("time=" + (Date.now() - start) + "ms") - t.end() -}) - -tap.test("global leak test", function (t) { - var globalAfter = Object.keys(global) - t.equivalent(globalAfter, globalBefore, "no new globals, please") - t.end() -}) - -function alpha (a, b) { - return a > b ? 1 : -1 -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js deleted file mode 100644 index 7ee278a2..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js +++ /dev/null @@ -1,33 +0,0 @@ -var tap = require("tap") - , minimatch = require("../") - -tap.test("brace expansion", function (t) { - // [ pattern, [expanded] ] - ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}" - , [ "abxy" - , "abxz" - , "acdxy" - , "acdxz" - , "acexy" - , "acexz" - , "afhxy" - , "afhxz" - , "aghxy" - , "aghxz" ] ] - , [ "a{1..5}b" - , [ "a1b" - , "a2b" - , "a3b" - , "a4b" - , "a5b" ] ] - , [ "a{b}c", ["a{b}c"] ] - ].forEach(function (tc) { - var p = tc[0] - , expect = tc[1] - t.equivalent(minimatch.braceExpand(p), expect, p) - }) - console.error("ending") - t.end() -}) - - diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js deleted file mode 100644 index 0fec4b0f..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js +++ /dev/null @@ -1,14 +0,0 @@ -var Minimatch = require("../minimatch.js").Minimatch -var tap = require("tap") -tap.test("cache test", function (t) { - var mm1 = new Minimatch("a?b") - var mm2 = new Minimatch("a?b") - t.equal(mm1, mm2, "should get the same object") - // the lru should drop it after 100 entries - for (var i = 0; i < 100; i ++) { - new Minimatch("a"+i) - } - mm2 = new Minimatch("a?b") - t.notEqual(mm1, mm2, "cache should have dropped") - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js deleted file mode 100644 index 75e05712..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js +++ /dev/null @@ -1,274 +0,0 @@ -// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test -// -// TODO: Some of these tests do very bad things with backslashes, and will -// most likely fail badly on windows. They should probably be skipped. - -var tap = require("tap") - , globalBefore = Object.keys(global) - , mm = require("../") - , files = [ "a", "b", "c", "d", "abc" - , "abd", "abe", "bb", "bcd" - , "ca", "cb", "dd", "de" - , "bdir/", "bdir/cfile"] - , next = files.concat([ "a-b", "aXb" - , ".x", ".y" ]) - -tap.test("basic tests", function (t) { - var start = Date.now() - - // [ pattern, [matches], MM opts, files, TAP opts] - ; [ "http://www.bashcookbook.com/bashinfo" + - "/source/bash-1.14.7/tests/glob-test" - , ["a*", ["a", "abc", "abd", "abe"]] - , ["X*", ["X*"], {nonull: true}] - - // allow null glob expansion - , ["X*", []] - - // isaacs: Slightly different than bash/sh/ksh - // \\* is not un-escaped to literal "*" in a failed match, - // but it does make it get treated as a literal star - , ["\\*", ["\\*"], {nonull: true}] - , ["\\**", ["\\**"], {nonull: true}] - , ["\\*\\*", ["\\*\\*"], {nonull: true}] - - , ["b*/", ["bdir/"]] - , ["c*", ["c", "ca", "cb"]] - , ["**", files] - - , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] - , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] - - , "legendary larry crashes bashes" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] - - , "character classes" - , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] - , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", - "bdir/", "ca", "cb", "dd", "de"]] - , ["a*[^c]", ["abd", "abe"]] - , function () { files.push("a-b", "aXb") } - , ["a[X-]b", ["a-b", "aXb"]] - , function () { files.push(".x", ".y") } - , ["[^a-c]*", ["d", "dd", "de"]] - , function () { files.push("a*b/", "a*b/ooo") } - , ["a\\*b/*", ["a*b/ooo"]] - , ["a\\*?/*", ["a*b/ooo"]] - , ["*\\\\!*", [], {null: true}, ["echo !7"]] - , ["*\\!*", ["echo !7"], null, ["echo !7"]] - , ["*.\\*", ["r.*"], null, ["r.*"]] - , ["a[b]c", ["abc"]] - , ["a[\\b]c", ["abc"]] - , ["a?c", ["abc"]] - , ["a\\*c", [], {null: true}, ["abc"]] - , ["", [""], { null: true }, [""]] - - , "http://www.opensource.apple.com/source/bash/bash-23/" + - "bash/tests/glob-test" - , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } - , ["*/man*/bash.*", ["man/man1/bash.1"]] - , ["man/man1/bash.1", ["man/man1/bash.1"]] - , ["a***c", ["abc"], null, ["abc"]] - , ["a*****?c", ["abc"], null, ["abc"]] - , ["?*****??", ["abc"], null, ["abc"]] - , ["*****??", ["abc"], null, ["abc"]] - , ["?*****?c", ["abc"], null, ["abc"]] - , ["?***?****c", ["abc"], null, ["abc"]] - , ["?***?****?", ["abc"], null, ["abc"]] - , ["?***?****", ["abc"], null, ["abc"]] - , ["*******c", ["abc"], null, ["abc"]] - , ["*******?", ["abc"], null, ["abc"]] - , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["[-abc]", ["-"], null, ["-"]] - , ["[abc-]", ["-"], null, ["-"]] - , ["\\", ["\\"], null, ["\\"]] - , ["[\\\\]", ["\\"], null, ["\\"]] - , ["[[]", ["["], null, ["["]] - , ["[", ["["], null, ["["]] - , ["[*", ["[abc"], null, ["[abc"]] - , "a right bracket shall lose its special meaning and\n" + - "represent itself in a bracket expression if it occurs\n" + - "first in the list. -- POSIX.2 2.8.3.2" - , ["[]]", ["]"], null, ["]"]] - , ["[]-]", ["]"], null, ["]"]] - , ["[a-\z]", ["p"], null, ["p"]] - , ["??**********?****?", [], { null: true }, ["abc"]] - , ["??**********?****c", [], { null: true }, ["abc"]] - , ["?************c****?****", [], { null: true }, ["abc"]] - , ["*c*?**", [], { null: true }, ["abc"]] - , ["a*****c*?**", [], { null: true }, ["abc"]] - , ["a********???*******", [], { null: true }, ["abc"]] - , ["[]", [], { null: true }, ["a"]] - , ["[abc", [], { null: true }, ["["]] - - , "nocase tests" - , ["XYZ", ["xYz"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["ab*", ["ABC"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - - // [ pattern, [matches], MM opts, files, TAP opts] - , "onestar/twostar" - , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] - , ["{/?,*}", ["/a", "bb"], {null: true} - , ["/a", "/b/b", "/a/b/c", "bb"]] - - , "dots should not match unless requested" - , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] - - // .. and . can only match patterns starting with ., - // even when options.dot is set. - , function () { - files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] - } - , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] - , ["a/*/b", ["a/c/b"], {dot:false}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] - - - // this also tests that changing the options needs - // to change the cache key, even if the pattern is - // the same! - , ["**", ["a/b","a/.d",".a/.d"], { dot: true } - , [ ".a/.d", "a/.d", "a/b"]] - - , "paren sets cannot contain slashes" - , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] - - // brace sets trump all else. - // - // invalid glob pattern. fails on bash4 and bsdglob. - // however, in this implementation, it's easier just - // to do the intuitive thing, and let brace-expansion - // actually come before parsing any extglob patterns, - // like the documentation seems to say. - // - // XXX: if anyone complains about this, either fix it - // or tell them to grow up and stop complaining. - // - // bash/bsdglob says this: - // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] - // but we do this instead: - , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] - - // test partial parsing in the presence of comment/negation chars - , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] - , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] - - // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. - , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] - , {} - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] - - - // crazy nested {,,} and *(||) tests. - , function () { - files = [ "a", "b", "c", "d" - , "ab", "ac", "ad" - , "bc", "cb" - , "bc,d", "c,db", "c,d" - , "d)", "(b|c", "*(b|c" - , "b|c", "b|cc", "cb|c" - , "x(a|b|c)", "x(a|c)" - , "(a|b|c)", "(a|c)"] - } - , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] - , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] - // a - // *(b|c) - // *(b|d) - , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] - , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] - - - // test various flag settings. - , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] - , { noext: true } ] - , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} - , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] - , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] - - - // begin channelling Boole and deMorgan... - , "negation tests" - , function () { - files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] - } - - // anything that is NOT a* matches. - , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] - - // anything that IS !a* matches. - , ["!a*", ["!ab", "!abc"], {nonegate: true}] - - // anything that IS a* matches - , ["!!a*", ["a!b"]] - - // anything that is NOT !a* matches - , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] - - // negation nestled within a pattern - , function () { - files = [ "foo.js" - , "foo.bar" - // can't match this one without negative lookbehind. - , "foo.js.js" - , "blar.js" - , "foo." - , "boo.js.boo" ] - } - , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] - - ].forEach(function (c) { - if (typeof c === "function") return c() - if (typeof c === "string") return t.comment(c) - - var pattern = c[0] - , expect = c[1].sort(alpha) - , options = c[2] - , f = c[3] || files - , tapOpts = c[4] || {} - - // options.debug = true - var Class = mm.defaults(options).Minimatch - var m = new Class(pattern, {}) - var r = m.makeRe() - tapOpts.re = String(r) || JSON.stringify(r) - tapOpts.files = JSON.stringify(f) - tapOpts.pattern = pattern - tapOpts.set = m.set - tapOpts.negated = m.negate - - var actual = mm.match(f, pattern, options) - actual.sort(alpha) - - t.equivalent( actual, expect - , JSON.stringify(pattern) + " " + JSON.stringify(expect) - , tapOpts ) - }) - - t.comment("time=" + (Date.now() - start) + "ms") - t.end() -}) - -tap.test("global leak test", function (t) { - var globalAfter = Object.keys(global) - t.equivalent(globalAfter, globalBefore, "no new globals, please") - t.end() -}) - -function alpha (a, b) { - return a > b ? 1 : -1 -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js deleted file mode 100644 index 6676e262..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js +++ /dev/null @@ -1,8 +0,0 @@ -var test = require('tap').test -var minimatch = require('../') - -test('extglob ending with statechar', function(t) { - t.notOk(minimatch('ax', 'a?(b*)')) - t.ok(minimatch('ax', '?(a*|b)')) - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json deleted file mode 100644 index e7ec15f3..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "name": "glob", - "description": "a little globber", - "version": "3.2.11", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "main": "glob.js", - "engines": { - "node": "*" - }, - "dependencies": { - "inherits": "2", - "minimatch": "0.3" - }, - "devDependencies": { - "tap": "~0.4.0", - "mkdirp": "0", - "rimraf": "1" - }, - "scripts": { - "test": "tap test/*.js", - "test-regen": "TEST_REGEN=1 node test/00-setup.js" - }, - "license": "BSD", - "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", - "bugs": { - "url": "https://github.com/isaacs/node-glob/issues" - }, - "homepage": "https://github.com/isaacs/node-glob", - "_id": "glob@3.2.11", - "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", - "_from": "glob@~3.2.9", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", - "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js deleted file mode 100644 index 245afafd..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/00-setup.js +++ /dev/null @@ -1,176 +0,0 @@ -// just a little pre-run script to set up the fixtures. -// zz-finish cleans it up - -var mkdirp = require("mkdirp") -var path = require("path") -var i = 0 -var tap = require("tap") -var fs = require("fs") -var rimraf = require("rimraf") - -var files = -[ "a/.abcdef/x/y/z/a" -, "a/abcdef/g/h" -, "a/abcfed/g/h" -, "a/b/c/d" -, "a/bc/e/f" -, "a/c/d/c/b" -, "a/cb/e/f" -] - -var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") -var symlinkFrom = "../.." - -files = files.map(function (f) { - return path.resolve(__dirname, f) -}) - -tap.test("remove fixtures", function (t) { - rimraf(path.resolve(__dirname, "a"), function (er) { - t.ifError(er, "remove fixtures") - t.end() - }) -}) - -files.forEach(function (f) { - tap.test(f, function (t) { - var d = path.dirname(f) - mkdirp(d, 0755, function (er) { - if (er) { - t.fail(er) - return t.bailout() - } - fs.writeFile(f, "i like tests", function (er) { - t.ifError(er, "make file") - t.end() - }) - }) - }) -}) - -if (process.platform !== "win32") { - tap.test("symlinky", function (t) { - var d = path.dirname(symlinkTo) - console.error("mkdirp", d) - mkdirp(d, 0755, function (er) { - t.ifError(er) - fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) { - t.ifError(er, "make symlink") - t.end() - }) - }) - }) -} - -;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { - w = "/tmp/glob-test/" + w - tap.test("create " + w, function (t) { - mkdirp(w, function (er) { - if (er) - throw er - t.pass(w) - t.end() - }) - }) -}) - - -// generate the bash pattern test-fixtures if possible -if (process.platform === "win32" || !process.env.TEST_REGEN) { - console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") - return -} - -var spawn = require("child_process").spawn; -var globs = - // put more patterns here. - // anything that would be directly in / should be in /tmp/glob-test - ["test/a/*/+(c|g)/./d" - ,"test/a/**/[cg]/../[cg]" - ,"test/a/{b,c,d,e,f}/**/g" - ,"test/a/b/**" - ,"test/**/g" - ,"test/a/abc{fed,def}/g/h" - ,"test/a/abc{fed/g,def}/**/" - ,"test/a/abc{fed/g,def}/**///**/" - ,"test/**/a/**/" - ,"test/+(a|b|c)/a{/,bc*}/**" - ,"test/*/*/*/f" - ,"test/**/f" - ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" - ,"{./*/*,/tmp/glob-test/*}" - ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! - ,"test/a/!(symlink)/**" - ] -var bashOutput = {} -var fs = require("fs") - -globs.forEach(function (pattern) { - tap.test("generate fixture " + pattern, function (t) { - var cmd = "shopt -s globstar && " + - "shopt -s extglob && " + - "shopt -s nullglob && " + - // "shopt >&2; " + - "eval \'for i in " + pattern + "; do echo $i; done\'" - var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) }) - var out = [] - cp.stdout.on("data", function (c) { - out.push(c) - }) - cp.stderr.pipe(process.stderr) - cp.on("close", function (code) { - out = flatten(out) - if (!out) - out = [] - else - out = cleanResults(out.split(/\r*\n/)) - - bashOutput[pattern] = out - t.notOk(code, "bash test should finish nicely") - t.end() - }) - }) -}) - -tap.test("save fixtures", function (t) { - var fname = path.resolve(__dirname, "bash-results.json") - var data = JSON.stringify(bashOutput, null, 2) + "\n" - fs.writeFile(fname, data, function (er) { - t.ifError(er) - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -function flatten (chunks) { - var s = 0 - chunks.forEach(function (c) { s += c.length }) - var out = new Buffer(s) - s = 0 - chunks.forEach(function (c) { - c.copy(out, s) - s += c.length - }) - - return out.toString().trim() -} - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js deleted file mode 100644 index 239ed1a9..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js +++ /dev/null @@ -1,63 +0,0 @@ -// basic test -// show that it does the same thing by default as the shell. -var tap = require("tap") -, child_process = require("child_process") -, bashResults = require("./bash-results.json") -, globs = Object.keys(bashResults) -, glob = require("../") -, path = require("path") - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -process.chdir(path.resolve(__dirname, "..")) - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -globs.forEach(function (pattern) { - var expect = bashResults[pattern] - // anything regarding the symlink thing will fail on windows, so just skip it - if (process.platform === "win32" && - expect.some(function (m) { - return /\/symlink\//.test(m) - })) - return - - tap.test(pattern, function (t) { - glob(pattern, function (er, matches) { - if (er) - throw er - - // sort and unmark, just to match the shell results - matches = cleanResults(matches) - - t.deepEqual(matches, expect, pattern) - t.end() - }) - }) - - tap.test(pattern + " sync", function (t) { - var matches = cleanResults(glob.sync(pattern)) - - t.deepEqual(matches, expect, "should match shell") - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') - }) -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json deleted file mode 100644 index 8051c723..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/bash-results.json +++ /dev/null @@ -1,351 +0,0 @@ -{ - "test/a/*/+(c|g)/./d": [ - "test/a/b/c/./d" - ], - "test/a/**/[cg]/../[cg]": [ - "test/a/abcdef/g/../g", - "test/a/abcfed/g/../g", - "test/a/b/c/../c", - "test/a/c/../c", - "test/a/c/d/c/../c", - "test/a/symlink/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c" - ], - "test/a/{b,c,d,e,f}/**/g": [], - "test/a/b/**": [ - "test/a/b", - "test/a/b/c", - "test/a/b/c/d" - ], - "test/**/g": [ - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/a/abc{fed,def}/g/h": [ - "test/a/abcdef/g/h", - "test/a/abcfed/g/h" - ], - "test/a/abc{fed/g,def}/**/": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/a/abc{fed/g,def}/**///**/": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/**/a/**/": [ - "test/a", - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/b", - "test/a/b/c", - "test/a/bc", - "test/a/bc/e", - "test/a/c", - "test/a/c/d", - "test/a/c/d/c", - "test/a/cb", - "test/a/cb/e", - "test/a/symlink", - "test/a/symlink/a", - "test/a/symlink/a/b", - "test/a/symlink/a/b/c", - "test/a/symlink/a/b/c/a", - "test/a/symlink/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b" - ], - "test/+(a|b|c)/a{/,bc*}/**": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcdef/g/h", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/abcfed/g/h" - ], - "test/*/*/*/f": [ - "test/a/bc/e/f", - "test/a/cb/e/f" - ], - "test/**/f": [ - "test/a/bc/e/f", - "test/a/cb/e/f" - ], - "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" - ], - "{./*/*,/tmp/glob-test/*}": [ - "./examples/g.js", - "./examples/usr-local.js", - "./node_modules/inherits", - "./node_modules/minimatch", - "./node_modules/mkdirp", - "./node_modules/rimraf", - "./node_modules/tap", - "./test/00-setup.js", - "./test/a", - "./test/bash-comparison.js", - "./test/bash-results.json", - "./test/cwd-test.js", - "./test/globstar-match.js", - "./test/mark.js", - "./test/new-glob-optional-options.js", - "./test/nocase-nomagic.js", - "./test/pause-resume.js", - "./test/readme-issue.js", - "./test/root-nomount.js", - "./test/root.js", - "./test/stat.js", - "./test/zz-cleanup.js", - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq" - ], - "{/tmp/glob-test/*,*}": [ - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq", - "examples", - "glob.js", - "LICENSE", - "node_modules", - "package.json", - "README.md", - "test" - ], - "test/a/!(symlink)/**": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcdef/g/h", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/abcfed/g/h", - "test/a/b", - "test/a/b/c", - "test/a/b/c/d", - "test/a/bc", - "test/a/bc/e", - "test/a/bc/e/f", - "test/a/c", - "test/a/c/d", - "test/a/c/d/c", - "test/a/c/d/c/b", - "test/a/cb", - "test/a/cb/e", - "test/a/cb/e/f" - ] -} diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js deleted file mode 100644 index 352c27ef..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/cwd-test.js +++ /dev/null @@ -1,55 +0,0 @@ -var tap = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -tap.test("changing cwd and searching for **/d", function (t) { - var glob = require('../') - var path = require('path') - t.test('.', function (t) { - glob('**/d', function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) - t.end() - }) - }) - - t.test('a', function (t) { - glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'b/c/d', 'c/d' ]) - t.end() - }) - }) - - t.test('a/b', function (t) { - glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) - t.end() - }) - }) - - t.test('a/b/', function (t) { - glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) - t.end() - }) - }) - - t.test('.', function (t) { - glob('**/d', {cwd: process.cwd()}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) - t.end() - }) - }) - - t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() - }) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js deleted file mode 100644 index 9b234fa2..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/globstar-match.js +++ /dev/null @@ -1,19 +0,0 @@ -var Glob = require("../glob.js").Glob -var test = require('tap').test - -test('globstar should not have dupe matches', function(t) { - var pattern = 'a/**/[gh]' - var g = new Glob(pattern, { cwd: __dirname }) - var matches = [] - g.on('match', function(m) { - console.error('match %j', m) - matches.push(m) - }) - g.on('end', function(set) { - console.error('set', set) - matches = matches.sort() - set = set.sort() - t.same(matches, set, 'should have same set of matches') - t.end() - }) -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js deleted file mode 100644 index bf411c0e..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/mark.js +++ /dev/null @@ -1,118 +0,0 @@ -var test = require("tap").test -var glob = require('../') -process.chdir(__dirname) - -// expose timing issues -var lag = 5 -glob.Glob.prototype._stat = function(o) { return function(f, cb) { - var args = arguments - setTimeout(function() { - o.call(this, f, cb) - }.bind(this), lag += 5) -}}(glob.Glob.prototype._stat) - - -test("mark, with **", function (t) { - glob("a/*b*/**", {mark: true}, function (er, results) { - if (er) - throw er - var expect = - [ 'a/abcdef/', - 'a/abcdef/g/', - 'a/abcdef/g/h', - 'a/abcfed/', - 'a/abcfed/g/', - 'a/abcfed/g/h', - 'a/b/', - 'a/b/c/', - 'a/b/c/d', - 'a/bc/', - 'a/bc/e/', - 'a/bc/e/f', - 'a/cb/', - 'a/cb/e/', - 'a/cb/e/f' ] - - t.same(results, expect) - t.end() - }) -}) - -test("mark, no / on pattern", function (t) { - glob("a/*", {mark: true}, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - - if (process.platform !== "win32") - expect.push('a/symlink/') - - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) - -test("mark=false, no / on pattern", function (t) { - glob("a/*", function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef', - 'a/abcfed', - 'a/b', - 'a/bc', - 'a/c', - 'a/cb' ] - - if (process.platform !== "win32") - expect.push('a/symlink') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /[^\/]$/) - }) -}) - -test("mark=true, / on pattern", function (t) { - glob("a/*/", {mark: true}, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) - -test("mark=false, / on pattern", function (t) { - glob("a/*/", function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js deleted file mode 100644 index 3e7dc5ac..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js +++ /dev/null @@ -1,10 +0,0 @@ -var Glob = require('../glob.js').Glob; -var test = require('tap').test; - -test('new glob, with cb, and no options', function (t) { - new Glob(__filename, function(er, results) { - if (er) throw er; - t.same(results, [__filename]); - t.end(); - }); -}); diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js deleted file mode 100644 index 2503f231..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js +++ /dev/null @@ -1,113 +0,0 @@ -var fs = require('fs'); -var test = require('tap').test; -var glob = require('../'); - -test('mock fs', function(t) { - var stat = fs.stat - var statSync = fs.statSync - var readdir = fs.readdir - var readdirSync = fs.readdirSync - - function fakeStat(path) { - var ret - switch (path.toLowerCase()) { - case '/tmp': case '/tmp/': - ret = { isDirectory: function() { return true } } - break - case '/tmp/a': - ret = { isDirectory: function() { return false } } - break - } - return ret - } - - fs.stat = function(path, cb) { - var f = fakeStat(path); - if (f) { - process.nextTick(function() { - cb(null, f) - }) - } else { - stat.call(fs, path, cb) - } - } - - fs.statSync = function(path) { - return fakeStat(path) || statSync.call(fs, path) - } - - function fakeReaddir(path) { - var ret - switch (path.toLowerCase()) { - case '/tmp': case '/tmp/': - ret = [ 'a', 'A' ] - break - case '/': - ret = ['tmp', 'tMp', 'tMP', 'TMP'] - } - return ret - } - - fs.readdir = function(path, cb) { - var f = fakeReaddir(path) - if (f) - process.nextTick(function() { - cb(null, f) - }) - else - readdir.call(fs, path, cb) - } - - fs.readdirSync = function(path) { - return fakeReaddir(path) || readdirSync.call(fs, path) - } - - t.pass('mocked') - t.end() -}) - -test('nocase, nomagic', function(t) { - var n = 2 - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - glob('/tmp/a', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - if (--n === 0) t.end() - }) - glob('/tmp/A', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - if (--n === 0) t.end() - }) -}) - -test('nocase, with some magic', function(t) { - t.plan(2) - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - }) - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - }) -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js deleted file mode 100644 index e1ffbab1..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/pause-resume.js +++ /dev/null @@ -1,73 +0,0 @@ -// show that no match events happen while paused. -var tap = require("tap") -, child_process = require("child_process") -// just some gnarly pattern with lots of matches -, pattern = "test/a/!(symlink)/**" -, bashResults = require("./bash-results.json") -, patterns = Object.keys(bashResults) -, glob = require("../") -, Glob = glob.Glob -, path = require("path") - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -process.chdir(path.resolve(__dirname, "..")) - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -var globResults = [] -tap.test("use a Glob object, and pause/resume it", function (t) { - var g = new Glob(pattern) - , paused = false - , res = [] - , expect = bashResults[pattern] - - g.on("pause", function () { - console.error("pause") - }) - - g.on("resume", function () { - console.error("resume") - }) - - g.on("match", function (m) { - t.notOk(g.paused, "must not be paused") - globResults.push(m) - g.pause() - t.ok(g.paused, "must be paused") - setTimeout(g.resume.bind(g), 10) - }) - - g.on("end", function (matches) { - t.pass("reached glob end") - globResults = cleanResults(globResults) - matches = cleanResults(matches) - t.deepEqual(matches, globResults, - "end event matches should be the same as match events") - - t.deepEqual(matches, expect, - "glob matches should be the same as bash results") - - t.end() - }) -}) - diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js deleted file mode 100644 index 0b4e0be2..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/readme-issue.js +++ /dev/null @@ -1,36 +0,0 @@ -var test = require("tap").test -var glob = require("../") - -var mkdirp = require("mkdirp") -var fs = require("fs") -var rimraf = require("rimraf") -var dir = __dirname + "/package" - -test("setup", function (t) { - mkdirp.sync(dir) - fs.writeFileSync(dir + "/package.json", "{}", "ascii") - fs.writeFileSync(dir + "/README", "x", "ascii") - t.pass("setup done") - t.end() -}) - -test("glob", function (t) { - var opt = { - cwd: dir, - nocase: true, - mark: true - } - - glob("README?(.*)", opt, function (er, files) { - if (er) - throw er - t.same(files, ["README"]) - t.end() - }) -}) - -test("cleanup", function (t) { - rimraf.sync(dir) - t.pass("clean") - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js deleted file mode 100644 index 3ac5979b..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root-nomount.js +++ /dev/null @@ -1,39 +0,0 @@ -var tap = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -tap.test("changing root and searching for /b*/**", function (t) { - var glob = require('../') - var path = require('path') - t.test('.', function (t) { - glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, []) - t.end() - }) - }) - - t.test('a', function (t) { - glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - t.end() - }) - }) - - t.test('root=a, cwd=a/b', function (t) { - glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - t.end() - }) - }) - - t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() - }) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js deleted file mode 100644 index 95c23f99..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/root.js +++ /dev/null @@ -1,46 +0,0 @@ -var t = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -var glob = require('../') -var path = require('path') - -t.test('.', function (t) { - glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { - t.ifError(er) - t.like(matches, []) - t.end() - }) -}) - - -t.test('a', function (t) { - console.error("root=" + path.resolve('a')) - glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { - t.ifError(er) - var wanted = [ - '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' - ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - }) - - t.like(matches, wanted) - t.end() - }) -}) - -t.test('root=a, cwd=a/b', function (t) { - glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - })) - t.end() - }) -}) - -t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js deleted file mode 100644 index 62917114..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/stat.js +++ /dev/null @@ -1,32 +0,0 @@ -var glob = require('../') -var test = require('tap').test -var path = require('path') - -test('stat all the things', function(t) { - var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname }) - var matches = [] - g.on('match', function(m) { - matches.push(m) - }) - var stats = [] - g.on('stat', function(m) { - stats.push(m) - }) - g.on('end', function(eof) { - stats = stats.sort() - matches = matches.sort() - eof = eof.sort() - t.same(stats, matches) - t.same(eof, matches) - var cache = Object.keys(this.statCache) - t.same(cache.map(function (f) { - return path.relative(__dirname, f) - }).sort(), matches) - - cache.forEach(function(c) { - t.equal(typeof this.statCache[c], 'object') - }, this) - - t.end() - }) -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js deleted file mode 100644 index e085f0fa..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js +++ /dev/null @@ -1,11 +0,0 @@ -// remove the fixtures -var tap = require("tap") -, rimraf = require("rimraf") -, path = require("path") - -tap.test("cleanup fixtures", function (t) { - rimraf(path.resolve(__dirname, "a"), function (er) { - t.ifError(er, "removed") - t.end() - }) -}) diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt deleted file mode 100644 index 49869bba..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright 2012-2013 The Dojo Foundation -Based on Underscore.js 1.5.2, copyright 2009-2013 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. \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md deleted file mode 100644 index 6f9598e8..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Lo-Dash v2.4.1 -A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features). - -## Download - -Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds. - -* Modern builds perfect for newer browsers/environments:
    -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js) - -* Compatibility builds for older environment support too:
    -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js) - -* Underscore builds to use as a drop-in replacement:
    -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js) - -CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed. - -Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method. - -## Dive in - -There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).
    -Check out DevDocs as a fast, organized, & searchable interface for our documentation. - -The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
    -A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). - -## Features *not* in Underscore - - * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) - * [_(…)](http://lodash.com/docs#_) supports intuitive chaining - * [_.at](http://lodash.com/docs#at) for cherry-picking collection values - * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazyâ€*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods - * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects - * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects - * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions - * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` - * [_.create](http://lodash.com/docs#create) for easier object inheritance - * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins - * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions - * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control - * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys - * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early - * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties - * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties - * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object` - * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object - * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions - * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend) - * [_.noop](http://lodash.com/docs#noop) for function placeholders - * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative - * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior - * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays - * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers - * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking - * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties - * [_.support](http://lodash.com/docs#support) for flagging environment features - * [_.template](http://lodash.com/docs#template) supports [*“importsâ€*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) - * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects - * [_.where](http://lodash.com/docs#where) supports deep object comparisons - * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union) - * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values - * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), & - [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks - * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), & - [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings - * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), & - [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluckâ€* & *“_.whereâ€* shorthands - * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), & - [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods - -## Resources - - * Podcasts - - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) - - * Posts - - [Say “Hello†to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) - - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) - - * Videos - - [Introduction](https://vimeo.com/44154599) - - [Origins](https://vimeo.com/44154600) - - [Optimizations & builds](https://vimeo.com/44154601) - - [Native method use](https://vimeo.com/48576012) - - [Testing](https://vimeo.com/45865290) - - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) - - A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). - -## Support - -Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
    -Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash). - -Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
    -[![Sauce Labs](http://lodash.com/_img/sauce.png)](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More") - -## Installation & usage - -In browsers: - -```html - -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm i --save lodash - -{sudo} npm i -g lodash -npm ln lodash -``` - -In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): - -```js -var _ = require('lodash'); -// or as Underscore -var _ = require('lodash/dist/lodash.underscore'); -``` - -**Notes:** - * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL - * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader: - -```js -require({ - 'packages': [ - { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } - ] -}, -['lodash'], function(_) { - console.log(_.VERSION); -}); -``` - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 23798ba8..00000000 --- a/spec/fixture/node_modules/grunt-cli/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,7157 +0,0 @@ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; - - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = {}; - - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; - - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; - - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; - - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + - - // line terminators - '\n\r\u2028\u2029' + - - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowedProps = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - errorClass = '[object Error]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; - - /** Used as the data object for `iteratorTemplate` */ - var iteratorData = { - 'args': '', - 'array': null, - 'bottom': '', - 'firstArg': '', - 'init': '', - 'keys': null, - 'loop': '', - 'shadowedProps': null, - 'support': null, - 'top': '', - 'useHas': false - }; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; - - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; - } - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } - - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; - - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); - - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; - } - } - } - - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; - - while (++index < length) { - var value = ac[index], - other = bc[index]; - - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; - - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; - - while (++index < length) { - result.push(array[index]); - } - return result; - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } - - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); - } - } - - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); - } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); - } - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ - var arrayRef = []; - - /** Used for native method references */ - var errorProto = Error.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; - - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); - - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; - - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to avoid iterating non-enumerable properties in IE < 9 */ - var nonEnumProps = {}; - nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; - nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; - nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; - nonEnumProps[objectClass] = { 'constructor': true }; - - (function() { - var length = shadowedProps.length; - while (length--) { - var key = shadowedProps[length]; - for (var className in nonEnumProps) { - if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { - nonEnumProps[className][key] = false; - } - } - } - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; - - /** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function() { - var ctor = function() { this.x = 1; }, - object = { '0': 1, 'length': 1 }, - props = []; - - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var key in new ctor) { props.push(key); } - for (key in arguments) { } - - /** - * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsClass = toString.call(arguments) == argsClass; - - /** - * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). - * - * @memberOf _.support - * @type boolean - */ - support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); - - /** - * Detect if `name` or `message` properties of `Error.prototype` are - * enumerable by default. (IE < 9, Safari < 5.1) - * - * @memberOf _.support - * @type boolean - */ - support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); - - /** - * Detect if `prototype` properties are enumerable by default. - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - * - * @memberOf _.support - * @type boolean - */ - support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if `arguments` object indexes are non-enumerable - * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumArgs = key != 0; - - /** - * Detect if properties shadowing those on `Object.prototype` are non-enumerable. - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumShadows = !/valueOf/.test(props); - - /** - * Detect if own properties are iterated after inherited properties (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.ownLast = props[0] != 'x'; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); - - /** - * Detect lack of support for accessing string characters by index. - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - * - * @memberOf _.support - * @type boolean - */ - support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) - * and that the JS engine errors when attempting to coerce an object to - * a string without a `toString` function. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); - } catch(e) { - support.nodeClass = true; - } - }(1)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Object} data The data object used to populate the text. - * @returns {string} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg) + - ', result = ' + - (obj.init) + - ';\nif (!iterable) return result;\n' + - (obj.top) + - ';'; - if (obj.array) { - __p += '\nvar length = iterable.length; index = -1;\nif (' + - (obj.array) + - ') { '; - if (support.unindexedChars) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } - __p += '\n while (++index < length) {\n ' + - (obj.loop) + - ';\n }\n}\nelse { '; - } else if (support.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop) + - ';\n }\n } else { '; - } - - if (support.enumPrototypes) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } - - if (support.enumErrorProps) { - __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; - } - - var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } - - if (obj.useHas && obj.keys) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; - if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - } else { - __p += '\n for (index in iterable) {\n'; - if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - if (support.nonEnumShadows) { - __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; - for (k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowedProps[k]) + - '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; - if (!obj.useHas) { - __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; - } - __p += ') {\n ' + - (obj.loop) + - ';\n } '; - } - __p += '\n } '; - } - - } - - if (obj.array || support.nonEnumArgs) { - __p += '\n}'; - } - __p += - (obj.bottom) + - ';\nreturn result'; - - return __p - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; - } - else { - result = isArr ? slice(value) : assign({}, value); - } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - // exit for shallow clone - if (!isDeep) { - return result; - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); - }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } - - /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. - */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; - - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(values); - } - return result; - } - - /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. - */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - } - stackA.pop(); - stackB.pop(); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - - /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. - * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. - */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; - - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; - - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; - } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; - } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; - } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); - } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); - } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {...Object} [options] The compile options object(s). - * @param {string} [options.array] Code to determine if the iterable is an array or array-like. - * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. - * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. - * @param {string} [options.args] A comma separated string of iteration function arguments. - * @param {string} [options.top] Code to execute before the iteration branches. - * @param {string} [options.loop] Code to execute in the object loop. - * @param {string} [options.bottom] Code to execute after the iteration branches. - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - // data properties - iteratorData.shadowedProps = shadowedProps; - - // iterator options - iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; - iteratorData.init = 'iterable'; - iteratorData.useHas = true; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - iteratorData[key] = object[key]; - } - } - var args = iteratorData.args; - iteratorData.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + - 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + - 'objectTypes, nonEnumProps, stringClass, stringProto, toString', - 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' - ); - - // return the compiled function - return factory( - baseCreateCallback, errorClass, errorProto, hasOwnProperty, - indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, - objectTypes, nonEnumProps, stringClass, stringProto, toString - ); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || - (!support.argsClass && isArguments(value)) || - (!support.nodeClass && isNode(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (support.ownLast) { - forIn(value, function(value, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (!support.argsClass) { - isArguments = function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; - }; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = createIterator({ - 'args': 'object', - 'init': '[]', - 'top': 'if (!(objectTypes[typeof object])) return result', - 'loop': 'result.push(index)' - }); - - /** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", - 'array': "typeof length == 'number'", - 'keys': keys, - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'keys': keys, - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'array': false - }; - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the callback for each - * element in the collection. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createIterator(eachIteratorOptions); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; - } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } - * }; - * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' - * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' - */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } - * }; - * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' - * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' - */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' - */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); - - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; - } - } - return object; - } - - /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } - } - return object; - } - - /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value && value.nodeType === 1 || false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - (support.argsClass ? className == argsClass : isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value == 'function' && toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; - } - - /** - * Checks if `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * _.isPlainObject(new Shape); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/fred/); - * // => true - */ - function isRegExp(value) { - return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('fred'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } - */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } - * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } - */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } - } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? baseEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); - } - return accumulator; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.contains('pebbles', 'eb'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - baseEach(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - - /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } - * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } - */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - } - - /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 - */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - baseEach(collection, callback, thisArg); - } - return collection; - } - - /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' - */ - function forEachRight(collection, callback, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (support.unindexedChars && isString(collection)) { - iterable = collection.split(''); - } - baseEach(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(iterable[key], key, collection); - }); - } - return collection; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = lodash.createCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; - * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the collection. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] - */ - var pluck = map; - - /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Retrieves a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } else if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] - * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); - } - releaseObject(object); - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (support.unindexedChars && isString(collection)) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] - * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; - * }); - * // => 2 - * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 - */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 - * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 - */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] - */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] - */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; - } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] - */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; - - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); - } - } - releaseArray(caches); - releaseArray(seen); - return result; - } - - /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. - * - * @static - * @memberOf _ - * @category Arrays - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); - * - * console.log(array); - * // => [1, 3, 5] - * - * console.log(evens); - * // => [2, 4, 6] - */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); - } - - /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); - } - - /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. - * - * @static - * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed - */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' - * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; - * - * func(); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } - - /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; - * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; - * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' - */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. - * @example - * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 - * - * curried(1, 2)(3); - * // => 6 - * - * curried(1, 2, 3); - * // => 6 - */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); - * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); - * - * // ensure `batchLog` is executed once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * source.addEventListener('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * }, false); - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - wait = nativeMax(0, wait) || 0; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); - trailing = 'trailing' in options ? options.trailing : trailing; - } - var delayed = function() { - var remaining = wait - (now() - stamp); - if (remaining <= 0) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - }; - - var maxDelayed = function() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - }; - - return function() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - }; - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay execution. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it will be used to determine the cache key for storing the result - * based on the arguments provided to the memoized function. By default, the - * first argument provided to the memoized function is used as the cache key. - * The `func` is executed with the `this` binding of the memoized function. - * The result cache is exposed as the `cache` property on the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - * - * fibonacci(9) - * // => 34 - * - * var data = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // modifying the result cache - * var get = _.memoize(function(name) { return data[name]; }, _.identity); - * get('pebbles'); - * // => { 'name': 'pebbles', 'age': 1 } - * - * get.cache.pebbles.name = 'penelope'; - * get('pebbles'); - * // => { 'name': 'penelope', 'age': 1 } - */ - function memoize(func, resolver) { - if (!isFunction(func)) { - throw new TypeError; - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; - - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - } - memoized.cache = {}; - return memoized; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those provided to the new function. This - * method is similar to `_.bind` except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('fred'); - * // => 'hi fred' - */ - function partial(func) { - return createWrapper(func, 16, slice(arguments, 1)); - } - - /** - * This method is like `_.partial` except that `partial` arguments are - * appended to those provided to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createWrapper(func, 32, null, slice(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` function - * at most once per every `wait` milliseconds. Provide an options object to - * indicate that `func` should be invoked on the leading and/or trailing edge - * of the `wait` timeout. Subsequent calls to the throttled function will - * return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle executions to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - * - * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? options.leading : leading; - trailing = 'trailing' in options ? options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = wait; - debounceOptions.trailing = trailing; - - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Additional arguments provided to the function are appended - * to those provided to the wrapper function. The wrapper is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

    ' + func(text) + '

    '; - * }); - * - * p('Fred, Wilma, & Pebbles'); - * // => '

    Fred, Wilma, & Pebbles

    ' - */ - function wrap(value, wrapper) { - return createWrapper(wrapper, 16, [value]); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. - * @example - * - * var object = { 'name': 'fred' }; - * var getter = _.constant(object); - * getter() === object; - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ - function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; - - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } - } - return result; - }; - } - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} string The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('Fred, Wilma, & Pebbles'); - * // => 'Fred, Wilma, & Pebbles' - */ - function escape(string) { - return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds function properties of a source object to the destination object. - * If `object` is a function methods will be added to its prototype as well. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Function|Object} [object=lodash] object The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options] The options object. - * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. - * @example - * - * function capitalize(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * - * _.mixin({ 'capitalize': capitalize }); - * _.capitalize('fred'); - * // => 'Fred' - * - * _('fred').capitalize().value(); - * // => 'Fred' - * - * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); - * _('fred').capitalize(); - * // => 'Fred' - */ - function mixin(object, source, options) { - var chain = true, - methodNames = source && functions(source); - - if (!source || (!options && !methodNames.length)) { - if (options == null) { - options = source; - } - ctor = lodashWrapper; - source = object; - object = lodash; - methodNames = functions(source); - } - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - var ctor = object, - isFunc = isFunction(ctor); - - forEach(methodNames, function(methodName) { - var func = object[methodName] = source[methodName]; - if (isFunc) { - ctor.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new ctor(result); - result.__chain__ = chainAll; - } - return result; - }; - } - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - context._ = oldDash; - return this; - } - - /** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ - function noop() { - // no operation performed - } - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var stamp = _.now(); - * _.defer(function() { console.log(_.now() - stamp); }); - * // => logs the number of milliseconds it took for the deferred function to be called - */ - var now = isNative(now = Date.now) && now || function() { - return new Date().getTime(); - }; - - /** - * Converts the given value into an integer of the specified radix. - * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the - * `value` is a hexadecimal, in which case a `radix` of `16` is used. - * - * Note: This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See http://es5.github.io/#E. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} value The value to parse. - * @param {number} [radix] The radix used to interpret the value to parse. - * @returns {number} Returns the new integer value. - * @example - * - * _.parseInt('08'); - * // => 8 - */ - var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` - return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); - }; - - /** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example - * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; - * - * var getName = _.property('name'); - * - * _.map(characters, getName); - * // => ['barney', 'fred'] - * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] - */ - function property(key) { - return function(object) { - return object[key]; - }; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number will be - * returned. If `floating` is truey or either `min` or `max` are floats a - * floating-point number will be returned instead of an integer. - * - * @static - * @memberOf _ - * @category Utilities - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating=false] Specify returning a floating-point number. - * @returns {number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (typeof min == 'boolean' && noMax) { - floating = min; - min = 1; - } - else if (!noMax && typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); - } - return baseRandom(min, max); - } - - /** - * Resolves the value of property `key` on `object`. If `key` is a function - * it will be invoked with the `this` binding of `object` and its result returned, - * else the property value is returned. If `object` is falsey then `undefined` - * is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to resolve. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, key) { - if (object) { - var value = object[key]; - return isFunction(value) ? object[key]() : value; - } - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * For more information on precompiling templates see: - * http://lodash.com/custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} text The template text. - * @param {Object} data The data object used to populate the text. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as local variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [sourceURL] The sourceURL of the template's compiled source. - * @param {string} [variable] The data object variable name. - * @returns {Function|string} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': ' - - - -## Documentation - -### Collections - -* [forEach](#forEach) -* [map](#map) -* [filter](#filter) -* [reject](#reject) -* [reduce](#reduce) -* [detect](#detect) -* [sortBy](#sortBy) -* [some](#some) -* [every](#every) -* [concat](#concat) - -### Control Flow - -* [series](#series) -* [parallel](#parallel) -* [whilst](#whilst) -* [until](#until) -* [waterfall](#waterfall) -* [queue](#queue) -* [auto](#auto) -* [iterator](#iterator) -* [apply](#apply) -* [nextTick](#nextTick) - -### Utils - -* [memoize](#memoize) -* [unmemoize](#unmemoize) -* [log](#log) -* [dir](#dir) -* [noConflict](#noConflict) - - -## Collections - - -### forEach(arr, iterator, callback) - -Applies an iterator function to each item in an array, in parallel. -The iterator is called with an item from the list and a callback for when it -has finished. If the iterator passes an error to this callback, the main -callback for the forEach function is immediately called with the error. - -Note, that since this function applies the iterator to each item in parallel -there is no guarantee that the iterator functions will complete in order. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed. -* callback(err) - A callback which is called after all the iterator functions - have finished, or an error has occurred. - -__Example__ - - // assuming openFiles is an array of file names and saveFile is a function - // to save the modified contents of that file: - - async.forEach(openFiles, saveFile, function(err){ - // if any of the saves produced an error, err would equal that error - }); - ---------------------------------------- - - -### forEachSeries(arr, iterator, callback) - -The same as forEach only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. This means the iterator functions will complete in order. - - ---------------------------------------- - - -### forEachLimit(arr, limit, iterator, callback) - -The same as forEach only the iterator is applied to batches of items in the -array, in series. The next batch of iterators is only called once the current -one has completed processing. - -__Arguments__ - -* arr - An array to iterate over. -* limit - How many items should be in each batch. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed. -* callback(err) - A callback which is called after all the iterator functions - have finished, or an error has occurred. - -__Example__ - - // Assume documents is an array of JSON objects and requestApi is a - // function that interacts with a rate-limited REST api. - - async.forEachLimit(documents, 20, requestApi, function(err){ - // if any of the saves produced an error, err would equal that error - }); ---------------------------------------- - - -### map(arr, iterator, callback) - -Produces a new array of values by mapping each value in the given array through -the iterator function. The iterator is called with an item from the array and a -callback for when it has finished processing. The callback takes 2 arguments, -an error and the transformed item from the array. If the iterator passes an -error to this callback, the main callback for the map function is immediately -called with the error. - -Note, that since this function applies the iterator to each item in parallel -there is no guarantee that the iterator functions will complete in order, however -the results array will be in the same order as the original array. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed - with an error (which can be null) and a transformed item. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array of the - transformed items from the original array. - -__Example__ - - async.map(['file1','file2','file3'], fs.stat, function(err, results){ - // results is now an array of stats for each file - }); - ---------------------------------------- - - -### mapSeries(arr, iterator, callback) - -The same as map only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - - ---------------------------------------- - - -### filter(arr, iterator, callback) - -__Alias:__ select - -Returns a new array of all the values which pass an async truth test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like path.exists. This operation is -performed in parallel, but the results array will be in the same order as the -original. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed. -* callback(results) - A callback which is called after all the iterator - functions have finished. - -__Example__ - - async.filter(['file1','file2','file3'], path.exists, function(results){ - // results now equals an array of the existing files - }); - ---------------------------------------- - - -### filterSeries(arr, iterator, callback) - -__alias:__ selectSeries - -The same as filter only the iterator is applied to each item in the array in -series. The next iterator is only called once the current one has completed -processing. The results array will be in the same order as the original. - ---------------------------------------- - - -### reject(arr, iterator, callback) - -The opposite of filter. Removes values that pass an async truth test. - ---------------------------------------- - - -### rejectSeries(arr, iterator, callback) - -The same as filter, only the iterator is applied to each item in the array -in series. - - ---------------------------------------- - - -### reduce(arr, memo, iterator, callback) - -__aliases:__ inject, foldl - -Reduces a list of values into a single value using an async iterator to return -each successive step. Memo is the initial state of the reduction. This -function only operates in series. For performance reasons, it may make sense to -split a call to this function into a parallel map, then use the normal -Array.prototype.reduce on the results. This function is for situations where -each step in the reduction needs to be async, if you can get the data before -reducing it then its probably a good idea to do so. - -__Arguments__ - -* arr - An array to iterate over. -* memo - The initial state of the reduction. -* iterator(memo, item, callback) - A function applied to each item in the - array to produce the next step in the reduction. The iterator is passed a - callback which accepts an optional error as its first argument, and the state - of the reduction as the second. If an error is passed to the callback, the - reduction is stopped and the main callback is immediately called with the - error. -* callback(err, result) - A callback which is called after all the iterator - functions have finished. Result is the reduced value. - -__Example__ - - async.reduce([1,2,3], 0, function(memo, item, callback){ - // pointless async: - process.nextTick(function(){ - callback(null, memo + item) - }); - }, function(err, result){ - // result is now equal to the last value of memo, which is 6 - }); - ---------------------------------------- - - -### reduceRight(arr, memo, iterator, callback) - -__Alias:__ foldr - -Same as reduce, only operates on the items in the array in reverse order. - - ---------------------------------------- - - -### detect(arr, iterator, callback) - -Returns the first value in a list that passes an async truth test. The -iterator is applied in parallel, meaning the first iterator to return true will -fire the detect callback with that result. That means the result might not be -the first item in the original array (in terms of order) that passes the test. - -If order within the original array is important then look at detectSeries. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed. -* callback(result) - A callback which is called as soon as any iterator returns - true, or after all the iterator functions have finished. Result will be - the first item in the array that passes the truth test (iterator) or the - value undefined if none passed. - -__Example__ - - async.detect(['file1','file2','file3'], path.exists, function(result){ - // result now equals the first file in the list that exists - }); - ---------------------------------------- - - -### detectSeries(arr, iterator, callback) - -The same as detect, only the iterator is applied to each item in the array -in series. This means the result is always the first in the original array (in -terms of array order) that passes the truth test. - - ---------------------------------------- - - -### sortBy(arr, iterator, callback) - -Sorts a list by the results of running each value through an async iterator. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed - with an error (which can be null) and a value to use as the sort criteria. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is the items from - the original array sorted by the values returned by the iterator calls. - -__Example__ - - async.sortBy(['file1','file2','file3'], function(file, callback){ - fs.stat(file, function(err, stats){ - callback(err, stats.mtime); - }); - }, function(err, results){ - // results is now the original array of files sorted by - // modified date - }); - - ---------------------------------------- - - -### some(arr, iterator, callback) - -__Alias:__ any - -Returns true if at least one element in the array satisfies an async test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like path.exists. Once any iterator -call returns true, the main callback is immediately called. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed. -* callback(result) - A callback which is called as soon as any iterator returns - true, or after all the iterator functions have finished. Result will be - either true or false depending on the values of the async tests. - -__Example__ - - async.some(['file1','file2','file3'], path.exists, function(result){ - // if result is true then at least one of the files exists - }); - ---------------------------------------- - - -### every(arr, iterator, callback) - -__Alias:__ all - -Returns true if every element in the array satisfies an async test. -_The callback for each iterator call only accepts a single argument of true or -false, it does not accept an error argument first!_ This is in-line with the -way node libraries work with truth tests like path.exists. - -__Arguments__ - -* arr - An array to iterate over. -* iterator(item, callback) - A truth test to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed. -* callback(result) - A callback which is called after all the iterator - functions have finished. Result will be either true or false depending on - the values of the async tests. - -__Example__ - - async.every(['file1','file2','file3'], path.exists, function(result){ - // if result is true then every file exists - }); - ---------------------------------------- - - -### concat(arr, iterator, callback) - -Applies an iterator to each item in a list, concatenating the results. Returns the -concatenated list. The iterators are called in parallel, and the results are -concatenated as they return. There is no guarantee that the results array will -be returned in the original order of the arguments passed to the iterator function. - -__Arguments__ - -* arr - An array to iterate over -* iterator(item, callback) - A function to apply to each item in the array. - The iterator is passed a callback which must be called once it has completed - with an error (which can be null) and an array of results. -* callback(err, results) - A callback which is called after all the iterator - functions have finished, or an error has occurred. Results is an array containing - the concatenated results of the iterator function. - -__Example__ - - async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ - // files is now a list of filenames that exist in the 3 directories - }); - ---------------------------------------- - - -### concatSeries(arr, iterator, callback) - -Same as async.concat, but executes in series instead of parallel. - - -## Control Flow - - -### series(tasks, [callback]) - -Run an array of functions in series, each one running once the previous -function has completed. If any functions in the series pass an error to its -callback, no more functions are run and the callback for the series is -immediately called with the value of the error. Once the tasks have completed, -the results are passed to the final callback as an array. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final callback as an object -instead of an array. This can be a more readable way of handling results from -async.series. - - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed - a callback it must call on completion. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets an array of all the arguments passed to - the callbacks used in the array. - -__Example__ - - async.series([ - function(callback){ - // do some stuff ... - callback(null, 'one'); - }, - function(callback){ - // do some more stuff ... - callback(null, 'two'); - }, - ], - // optional callback - function(err, results){ - // results is now equal to ['one', 'two'] - }); - - - // an example using an object instead of an array - async.series({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - }, - }, - function(err, results) { - // results is now equal to: {one: 1, two: 2} - }); - - ---------------------------------------- - - -### parallel(tasks, [callback]) - -Run an array of functions in parallel, without waiting until the previous -function has completed. If any of the functions pass an error to its -callback, the main callback is immediately called with the value of the error. -Once the tasks have completed, the results are passed to the final callback as an -array. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final callback as an object -instead of an array. This can be a more readable way of handling results from -async.parallel. - - -__Arguments__ - -* tasks - An array or object containing functions to run, each function is passed a - callback it must call on completion. -* callback(err, results) - An optional callback to run once all the functions - have completed. This function gets an array of all the arguments passed to - the callbacks used in the array. - -__Example__ - - async.parallel([ - function(callback){ - setTimeout(function(){ - callback(null, 'one'); - }, 200); - }, - function(callback){ - setTimeout(function(){ - callback(null, 'two'); - }, 100); - }, - ], - // optional callback - function(err, results){ - // the results array will equal ['one','two'] even though - // the second function had a shorter timeout. - }); - - - // an example using an object instead of an array - async.parallel({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - }, - }, - function(err, results) { - // results is now equals to: {one: 1, two: 2} - }); - - ---------------------------------------- - - -### whilst(test, fn, callback) - -Repeatedly call fn, while test returns true. Calls the callback when stopped, -or an error occurs. - -__Arguments__ - -* test() - synchronous truth test to perform before each execution of fn. -* fn(callback) - A function to call each time the test passes. The function is - passed a callback which must be called once it has completed with an optional - error as the first argument. -* callback(err) - A callback which is called after the test fails and repeated - execution of fn has stopped. - -__Example__ - - var count = 0; - - async.whilst( - function () { return count < 5; }, - function (callback) { - count++; - setTimeout(callback, 1000); - }, - function (err) { - // 5 seconds have passed - } - ); - - ---------------------------------------- - - -### until(test, fn, callback) - -Repeatedly call fn, until test returns true. Calls the callback when stopped, -or an error occurs. - -The inverse of async.whilst. - - ---------------------------------------- - - -### waterfall(tasks, [callback]) - -Runs an array of functions in series, each passing their results to the next in -the array. However, if any of the functions pass an error to the callback, the -next function is not executed and the main callback is immediately called with -the error. - -__Arguments__ - -* tasks - An array of functions to run, each function is passed a callback it - must call on completion. -* callback(err, [results]) - An optional callback to run once all the functions - have completed. This will be passed the results of the last task's callback. - - - -__Example__ - - async.waterfall([ - function(callback){ - callback(null, 'one', 'two'); - }, - function(arg1, arg2, callback){ - callback(null, 'three'); - }, - function(arg1, callback){ - // arg1 now equals 'three' - callback(null, 'done'); - } - ], function (err, result) { - // result now equals 'done' - }); - - ---------------------------------------- - - -### queue(worker, concurrency) - -Creates a queue object with the specified concurrency. Tasks added to the -queue will be processed in parallel (up to the concurrency limit). If all -workers are in progress, the task is queued until one is available. Once -a worker has completed a task, the task's callback is called. - -__Arguments__ - -* worker(task, callback) - An asynchronous function for processing a queued - task. -* concurrency - An integer for determining how many worker functions should be - run in parallel. - -__Queue objects__ - -The queue object returned by this function has the following properties and -methods: - -* length() - a function returning the number of items waiting to be processed. -* concurrency - an integer for determining how many worker functions should be - run in parallel. This property can be changed after a queue is created to - alter the concurrency on-the-fly. -* push(task, [callback]) - add a new task to the queue, the callback is called - once the worker has finished processing the task. - instead of a single task, an array of tasks can be submitted. the respective callback is used for every task in the list. -* saturated - a callback that is called when the queue length hits the concurrency and further tasks will be queued -* empty - a callback that is called when the last item from the queue is given to a worker -* drain - a callback that is called when the last item from the queue has returned from the worker - -__Example__ - - // create a queue object with concurrency 2 - - var q = async.queue(function (task, callback) { - console.log('hello ' + task.name); - callback(); - }, 2); - - - // assign a callback - q.drain = function() { - console.log('all items have been processed'); - } - - // add some items to the queue - - q.push({name: 'foo'}, function (err) { - console.log('finished processing foo'); - }); - q.push({name: 'bar'}, function (err) { - console.log('finished processing bar'); - }); - - // add some items to the queue (batch-wise) - - q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { - console.log('finished processing bar'); - }); - - ---------------------------------------- - - -### auto(tasks, [callback]) - -Determines the best order for running functions based on their requirements. -Each function can optionally depend on other functions being completed first, -and each function is run as soon as its requirements are satisfied. If any of -the functions pass an error to their callback, that function will not complete -(so any other functions depending on it will not run) and the main callback -will be called immediately with the error. Functions also receive an object -containing the results of functions which have completed so far. - -__Arguments__ - -* tasks - An object literal containing named functions or an array of - requirements, with the function itself the last item in the array. The key - used for each function or array is used when specifying requirements. The - syntax is easier to understand by looking at the example. -* callback(err, results) - An optional callback which is called when all the - tasks have been completed. The callback will receive an error as an argument - if any tasks pass an error to their callback. If all tasks complete - successfully, it will receive an object containing their results. - -__Example__ - - async.auto({ - get_data: function(callback){ - // async code to get some data - }, - make_folder: function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - }, - write_file: ['get_data', 'make_folder', function(callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - callback(null, filename); - }], - email_link: ['write_file', function(callback, results){ - // once the file is written let's email a link to it... - // results.write_file contains the filename returned by write_file. - }] - }); - -This is a fairly trivial example, but to do this using the basic parallel and -series functions would look like this: - - async.parallel([ - function(callback){ - // async code to get some data - }, - function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - } - ], - function(results){ - async.series([ - function(callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - }, - email_link: function(callback){ - // once the file is written let's email a link to it... - } - ]); - }); - -For a complicated series of async tasks using the auto function makes adding -new tasks much easier and makes the code more readable. - - ---------------------------------------- - - -### iterator(tasks) - -Creates an iterator function which calls the next function in the array, -returning a continuation to call the next one after that. Its also possible to -'peek' the next iterator by doing iterator.next(). - -This function is used internally by the async module but can be useful when -you want to manually control the flow of functions in series. - -__Arguments__ - -* tasks - An array of functions to run, each function is passed a callback it - must call on completion. - -__Example__ - - var iterator = async.iterator([ - function(){ sys.p('one'); }, - function(){ sys.p('two'); }, - function(){ sys.p('three'); } - ]); - - node> var iterator2 = iterator(); - 'one' - node> var iterator3 = iterator2(); - 'two' - node> iterator3(); - 'three' - node> var nextfn = iterator2.next(); - node> nextfn(); - 'three' - - ---------------------------------------- - - -### apply(function, arguments..) - -Creates a continuation function with some arguments already applied, a useful -shorthand when combined with other control flow functions. Any arguments -passed to the returned function are added to the arguments originally passed -to apply. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to automatically apply when the - continuation is called. - -__Example__ - - // using apply - - async.parallel([ - async.apply(fs.writeFile, 'testfile1', 'test1'), - async.apply(fs.writeFile, 'testfile2', 'test2'), - ]); - - - // the same process without using apply - - async.parallel([ - function(callback){ - fs.writeFile('testfile1', 'test1', callback); - }, - function(callback){ - fs.writeFile('testfile2', 'test2', callback); - }, - ]); - -It's possible to pass any number of additional arguments when calling the -continuation: - - node> var fn = async.apply(sys.puts, 'one'); - node> fn('two', 'three'); - one - two - three - ---------------------------------------- - - -### nextTick(callback) - -Calls the callback on a later loop around the event loop. In node.js this just -calls process.nextTick, in the browser it falls back to setTimeout(callback, 0), -which means other higher priority events may precede the execution of the callback. - -This is used internally for browser-compatibility purposes. - -__Arguments__ - -* callback - The function to call on a later loop around the event loop. - -__Example__ - - var call_order = []; - async.nextTick(function(){ - call_order.push('two'); - // call_order now equals ['one','two] - }); - call_order.push('one') - - -## Utils - - -### memoize(fn, [hasher]) - -Caches the results of an async function. When creating a hash to store function -results against, the callback is omitted from the hash and an optional hash -function can be used. - -__Arguments__ - -* fn - the function you to proxy and cache results from. -* hasher - an optional function for generating a custom hash for storing - results, it has all the arguments applied to it apart from the callback, and - must be synchronous. - -__Example__ - - var slow_fn = function (name, callback) { - // do something - callback(null, result); - }; - var fn = async.memoize(slow_fn); - - // fn can now be used as if it were slow_fn - fn('some name', function () { - // callback - }); - - -### unmemoize(fn) - -Undoes a memoized function, reverting it to the original, unmemoized -form. Comes handy in tests. - -__Arguments__ - -* fn - the memoized function - - -### log(function, arguments) - -Logs the result of an async function to the console. Only works in node.js or -in browsers that support console.log and console.error (such as FF and Chrome). -If multiple arguments are returned from the async function, console.log is -called on each argument in order. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to apply to the function. - -__Example__ - - var hello = function(name, callback){ - setTimeout(function(){ - callback(null, 'hello ' + name); - }, 1000); - }; - - node> async.log(hello, 'world'); - 'hello world' - - ---------------------------------------- - - -### dir(function, arguments) - -Logs the result of an async function to the console using console.dir to -display the properties of the resulting object. Only works in node.js or -in browsers that support console.dir and console.error (such as FF and Chrome). -If multiple arguments are returned from the async function, console.dir is -called on each argument in order. - -__Arguments__ - -* function - The function you want to eventually apply all arguments to. -* arguments... - Any number of arguments to apply to the function. - -__Example__ - - var hello = function(name, callback){ - setTimeout(function(){ - callback(null, {hello: name}); - }, 1000); - }; - - node> async.dir(hello, 'world'); - {hello: 'world'} - - ---------------------------------------- - - -### noConflict() - -Changes the value of async back to its original value, returning a reference to the -async object. diff --git a/spec/fixture/node_modules/grunt/node_modules/async/index.js b/spec/fixture/node_modules/grunt/node_modules/async/index.js deleted file mode 100644 index 8e238453..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/async/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// This file is just added for convenience so this repository can be -// directly checked out into a project's deps folder -module.exports = require('./lib/async'); diff --git a/spec/fixture/node_modules/grunt/node_modules/async/lib/async.js b/spec/fixture/node_modules/grunt/node_modules/async/lib/async.js deleted file mode 100644 index 7cc4f5ea..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/async/lib/async.js +++ /dev/null @@ -1,692 +0,0 @@ -/*global setTimeout: false, console: false */ -(function () { - - var async = {}; - - // global on the server, window in the browser - var root = this, - previous_async = root.async; - - if (typeof module !== 'undefined' && module.exports) { - module.exports = async; - } - else { - root.async = async; - } - - async.noConflict = function () { - root.async = previous_async; - return async; - }; - - //// cross-browser compatiblity functions //// - - var _forEach = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; - - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _forEach(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; - - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); - } - _forEach(arr, function (x, i, a) { - memo = iterator(memo, x, i, a); - }); - return memo; - }; - - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); - } - var keys = []; - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - keys.push(k); - } - } - return keys; - }; - - //// exported async module functions //// - - //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - } - else { - async.nextTick = process.nextTick; - } - - async.forEach = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - _forEach(arr, function (x) { - iterator(x, function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(null); - } - } - }); - }); - }; - - async.forEachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed === arr.length) { - callback(null); - } - else { - iterate(); - } - } - }); - }; - iterate(); - }; - - async.forEachLimit = function (arr, limit, iterator, callback) { - callback = callback || function () {}; - if (!arr.length || limit <= 0) { - return callback(); - } - var completed = 0; - var started = 0; - var running = 0; - - (function replenish () { - if (completed === arr.length) { - return callback(); - } - - while (running < limit && started < arr.length) { - started += 1; - running += 1; - iterator(arr[started - 1], function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - running -= 1; - if (completed === arr.length) { - callback(); - } - else { - replenish(); - } - } - }); - } - })(); - }; - - - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEach].concat(args)); - }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.forEachSeries].concat(args)); - }; - }; - - - var _asyncMap = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - }; - async.map = doParallel(_asyncMap); - async.mapSeries = doSeries(_asyncMap); - - - // reduce only has a series version, as doing reduce in parallel won't - // work in many situations. - async.reduce = function (arr, memo, iterator, callback) { - async.forEachSeries(arr, function (x, callback) { - iterator(memo, x, function (err, v) { - memo = v; - callback(err); - }); - }, function (err) { - callback(err, memo); - }); - }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; - - async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); - async.reduce(reversed, memo, iterator, callback); - }; - // foldr alias - async.foldr = async.reduceRight; - - var _filter = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; - - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); - }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; - async.reject = doParallel(_reject); - async.rejectSeries = doSeries(_reject); - - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - main_callback = function () {}; - } - else { - callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); - - async.some = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; - - async.every = function (arr, iterator, main_callback) { - async.forEach(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; - - async.sortBy = function (arr, iterator, callback) { - async.map(arr, function (x, callback) { - iterator(x, function (err, criteria) { - if (err) { - callback(err); - } - else { - callback(null, {value: x, criteria: criteria}); - } - }); - }, function (err, results) { - if (err) { - return callback(err); - } - else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { - return x.value; - })); - } - }); - }; - - async.auto = function (tasks, callback) { - callback = callback || function () {}; - var keys = _keys(tasks); - if (!keys.length) { - return callback(null); - } - - var results = {}; - - var listeners = []; - var addListener = function (fn) { - listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - _forEach(listeners.slice(0), function (fn) { - fn(); - }); - }; - - addListener(function () { - if (_keys(results).length === keys.length) { - callback(null, results); - callback = function () {}; - } - }); - - _forEach(keys, function (k) { - var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; - var taskCallback = function (err) { - if (err) { - callback(err); - // stop subsequent errors hitting callback multiple times - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - taskComplete(); - } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { - return _reduce(requires, function (a, x) { - return (a && results.hasOwnProperty(x)); - }, true) && !results.hasOwnProperty(k); - }; - if (ready()) { - task[task.length - 1](taskCallback, results); - } - else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback, results); - } - }; - addListener(listener); - } - }); - }; - - async.waterfall = function (tasks, callback) { - callback = callback || function () {}; - if (!tasks.length) { - return callback(); - } - var wrapIterator = function (iterator) { - return function (err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - var args = Array.prototype.slice.call(arguments, 1); - var next = iterator.next(); - if (next) { - args.push(wrapIterator(next)); - } - else { - args.push(callback); - } - async.nextTick(function () { - iterator.apply(null, args); - }); - } - }; - }; - wrapIterator(async.iterator(tasks))(); - }; - - async.parallel = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.forEach(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (tasks.constructor === Array) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.forEachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; - - async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { - if (tasks.length) { - tasks[index].apply(null, arguments); - } - return fn.next(); - }; - fn.next = function () { - return (index < tasks.length - 1) ? makeCallback(index + 1): null; - }; - return fn; - }; - return makeCallback(0); - }; - - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { - return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) - ); - }; - }; - - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { - fn(x, function (err, y) { - r = r.concat(y || []); - cb(err); - }); - }, function (err) { - callback(err, r); - }); - }; - async.concat = doParallel(_concat); - async.concatSeries = doSeries(_concat); - - async.whilst = function (test, iterator, callback) { - if (test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.whilst(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } - }; - - async.queue = function (worker, concurrency) { - var workers = 0; - var q = { - tasks: [], - concurrency: concurrency, - saturated: null, - empty: null, - drain: null, - push: function (data, callback) { - if(data.constructor !== Array) { - data = [data]; - } - _forEach(data, function(task) { - q.tasks.push({ - data: task, - callback: typeof callback === 'function' ? callback : null - }); - if (q.saturated && q.tasks.length == concurrency) { - q.saturated(); - } - async.nextTick(q.process); - }); - }, - process: function () { - if (workers < q.concurrency && q.tasks.length) { - var task = q.tasks.shift(); - if(q.empty && q.tasks.length == 0) q.empty(); - workers += 1; - worker(task.data, function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - if(q.drain && q.tasks.length + workers == 0) q.drain(); - q.process(); - }); - } - }, - length: function () { - return q.tasks.length; - }, - running: function () { - return workers; - } - }; - return q; - }; - - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (typeof console !== 'undefined') { - if (err) { - if (console.error) { - console.error(err); - } - } - else if (console[name]) { - _forEach(args, function (x) { - console[name](x); - }); - } - } - }])); - }; - }; - async.log = _console_fn('log'); - async.dir = _console_fn('dir'); - /*async.info = _console_fn('info'); - async.warn = _console_fn('warn'); - async.error = _console_fn('error');*/ - - async.memoize = function (fn, hasher) { - var memo = {}; - var queues = {}; - hasher = hasher || function (x) { - return x; - }; - var memoized = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var key = hasher.apply(null, args); - if (key in memo) { - callback.apply(null, memo[key]); - } - else if (key in queues) { - queues[key].push(callback); - } - else { - queues[key] = [callback]; - fn.apply(null, args.concat([function () { - memo[key] = arguments; - var q = queues[key]; - delete queues[key]; - for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); - } - }])); - } - }; - memoized.unmemoized = fn; - return memoized; - }; - - async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; - }; - -}()); diff --git a/spec/fixture/node_modules/grunt/node_modules/async/package.json b/spec/fixture/node_modules/grunt/node_modules/async/package.json deleted file mode 100644 index 29bf9131..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/async/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "async", - "description": "Higher-order functions and common patterns for asynchronous code", - "main": "./index", - "author": { - "name": "Caolan McMahon" - }, - "version": "0.1.22", - "repository": { - "type": "git", - "url": "git://github.com/caolan/async.git" - }, - "bugs": { - "url": "http://github.com/caolan/async/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/caolan/async/raw/master/LICENSE" - } - ], - "devDependencies": { - "nodeunit": ">0.0.0", - "uglify-js": "1.2.x", - "nodelint": ">0.0.0" - }, - "_npmUser": { - "name": "caolan", - "email": "caolan@caolanmcmahon.com" - }, - "_id": "async@0.1.22", - "dependencies": {}, - "optionalDependencies": {}, - "engines": { - "node": "*" - }, - "_engineSupported": true, - "_npmVersion": "1.1.21", - "_nodeVersion": "v0.6.18", - "_defaultsLoaded": true, - "dist": { - "shasum": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061", - "tarball": "http://registry.npmjs.org/async/-/async-0.1.22.tgz" - }, - "maintainers": [ - { - "name": "caolan", - "email": "caolan@caolanmcmahon.com" - } - ], - "directories": {}, - "_shasum": "0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061", - "_from": "async@~0.1.22", - "_resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", - "readme": "ERROR: No README data found!", - "homepage": "https://github.com/caolan/async", - "scripts": {} -} diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore b/spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore deleted file mode 100644 index 21e430d2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/.npmignore +++ /dev/null @@ -1,11 +0,0 @@ -*.coffee -*.html -.DS_Store -.git* -Cakefile -documentation/ -examples/ -extras/coffee-script.js -raw/ -src/ -test/ diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME b/spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME deleted file mode 100644 index faadabe5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/CNAME +++ /dev/null @@ -1 +0,0 @@ -coffeescript.org \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE b/spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE deleted file mode 100644 index dbe6b4e3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2009-2012 Jeremy Ashkenas - -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/spec/fixture/node_modules/grunt/node_modules/coffee-script/README b/spec/fixture/node_modules/grunt/node_modules/coffee-script/README deleted file mode 100644 index 69ee6f43..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/README +++ /dev/null @@ -1,51 +0,0 @@ - - { - } } { - { { } } - } }{ { - { }{ } } _____ __ __ - ( }{ }{ { ) / ____| / _|/ _| - .- { { } { }} -. | | ___ | |_| |_ ___ ___ - ( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \ - |`-..________ ..-'| | |___| (_) | | | || __/ __/ - | | \_____\___/|_| |_| \___|\___| - | ;--. - | (__ \ _____ _ _ - | | ) ) / ____| (_) | | - | |/ / | (___ ___ _ __ _ _ __ | |_ - | ( / \___ \ / __| '__| | '_ \| __| - | |/ ____) | (__| | | | |_) | |_ - | | |_____/ \___|_| |_| .__/ \__| - `-.._________..-' | | - |_| - - - CoffeeScript is a little language that compiles into JavaScript. - - Install Node.js, and then the CoffeeScript compiler: - sudo bin/cake install - - Or, if you have the Node Package Manager installed: - npm install -g coffee-script - (Leave off the -g if you don't wish to install globally.) - - Execute a script: - coffee /path/to/script.coffee - - Compile a script: - coffee -c /path/to/script.coffee - - For documentation, usage, and examples, see: - http://coffeescript.org/ - - To suggest a feature, report a bug, or general discussion: - http://github.com/jashkenas/coffee-script/issues/ - - If you'd like to chat, drop by #coffeescript on Freenode IRC, - or on webchat.freenode.net. - - The source repository: - git://github.com/jashkenas/coffee-script.git - - All contributors are listed here: - http://github.com/jashkenas/coffee-script/contributors diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile b/spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile deleted file mode 100644 index dfb85dab..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/Rakefile +++ /dev/null @@ -1,78 +0,0 @@ -require 'rubygems' -require 'erb' -require 'fileutils' -require 'rake/testtask' -require 'json' - -desc "Build the documentation page" -task :doc do - source = 'documentation/index.html.erb' - child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" } - at_exit { Process.kill("INT", child) } - Signal.trap("INT") { exit } - loop do - mtime = File.stat(source).mtime - if !@mtime || mtime > @mtime - rendered = ERB.new(File.read(source)).result(binding) - File.open('index.html', 'w+') {|f| f.write(rendered) } - end - @mtime = mtime - sleep 1 - end -end - -desc "Build coffee-script-source gem" -task :gem do - require 'rubygems' - require 'rubygems/package' - - gemspec = Gem::Specification.new do |s| - s.name = 'coffee-script-source' - s.version = JSON.parse(File.read('package.json'))["version"] - s.date = Time.now.strftime("%Y-%m-%d") - - s.homepage = "http://jashkenas.github.com/coffee-script/" - s.summary = "The CoffeeScript Compiler" - s.description = <<-EOS - CoffeeScript is a little language that compiles into JavaScript. - Underneath all of those embarrassing braces and semicolons, - JavaScript has always had a gorgeous object model at its heart. - CoffeeScript is an attempt to expose the good parts of JavaScript - in a simple way. - EOS - - s.files = [ - 'lib/coffee_script/coffee-script.js', - 'lib/coffee_script/source.rb' - ] - - s.authors = ['Jeremy Ashkenas'] - s.email = 'jashkenas@gmail.com' - s.rubyforge_project = 'coffee-script-source' - end - - file = File.open("coffee-script-source.gem", "w") - Gem::Package.open(file, 'w') do |pkg| - pkg.metadata = gemspec.to_yaml - - path = "lib/coffee_script/source.rb" - contents = <<-ERUBY -module CoffeeScript - module Source - def self.bundled_path - File.expand_path("../coffee-script.js", __FILE__) - end - end -end - ERUBY - pkg.add_file_simple(path, 0644, contents.size) do |tar_io| - tar_io.write(contents) - end - - contents = File.read("extras/coffee-script.js") - path = "lib/coffee_script/coffee-script.js" - pkg.add_file_simple(path, 0644, contents.size) do |tar_io| - tar_io.write(contents) - end - end -end diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake b/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake deleted file mode 100755 index 5965f4ee..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/cake +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node - -var path = require('path'); -var fs = require('fs'); -var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); - -require(lib + '/coffee-script/cake').run(); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee b/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee deleted file mode 100755 index 3d1d71c8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/bin/coffee +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node - -var path = require('path'); -var fs = require('fs'); -var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib'); - -require(lib + '/coffee-script/command').run(); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf b/spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf deleted file mode 100644 index 1190da52..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/extras/jsl.conf +++ /dev/null @@ -1,44 +0,0 @@ -# JavaScriptLint configuration file for CoffeeScript. - -+no_return_value # function {0} does not always return a value -+duplicate_formal # duplicate formal argument {0} --equal_as_assign # test for equality (==) mistyped as assignment (=)?{0} -+var_hides_arg # variable {0} hides argument -+redeclared_var # redeclaration of {0} {1} --anon_no_return_value # anonymous function does not always return a value -+missing_semicolon # missing semicolon -+meaningless_block # meaningless block; curly braces have no impact --comma_separated_stmts # multiple statements separated by commas (use semicolons?) -+unreachable_code # unreachable code -+missing_break # missing break statement --missing_break_for_last_case # missing break statement for last case in switch --comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) --inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement --useless_void # use of the void type may be unnecessary (void is always undefined) -+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs -+use_of_label # use of label --block_without_braces # block statement without curly braces -+leading_decimal_point # leading decimal point may indicate a number or an object member -+trailing_decimal_point # trailing decimal point may indicate a number or an object member -+octal_number # leading zeros make an octal number -+nested_comment # nested comment -+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma -+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement -+empty_statement # empty statement or extra semicolon --missing_option_explicit # the "option explicit" control comment is missing -+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag -+dup_option_explicit # duplicate "option explicit" control comment -+useless_assign # useless assignment -+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity -+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent) --missing_default_case # missing default case in switch statement -+duplicate_case_in_switch # duplicate case in switch statements -+default_not_at_end # the default case is not at the end of the switch statement -+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax -+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax -+useless_comparison # useless comparison; comparing identical expressions -+with_statement # with statement hides undeclared variables; use temporary variable instead -+trailing_comma_in_array # extra comma is not recommended in array initializers -+assign_to_function_call # assignment to a function call -+parseint_missing_radix # parseInt missing radix parameter -+lambda_assign_requires_semicolon diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js deleted file mode 100644 index 825cbf31..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/browser.js +++ /dev/null @@ -1,92 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var CoffeeScript, runScripts; - - CoffeeScript = require('./coffee-script'); - - CoffeeScript.require = require; - - CoffeeScript["eval"] = function(code, options) { - var _ref; - if (options == null) { - options = {}; - } - if ((_ref = options.bare) == null) { - options.bare = true; - } - return eval(CoffeeScript.compile(code, options)); - }; - - CoffeeScript.run = function(code, options) { - if (options == null) { - options = {}; - } - options.bare = true; - return Function(CoffeeScript.compile(code, options))(); - }; - - if (typeof window === "undefined" || window === null) { - return; - } - - CoffeeScript.load = function(url, callback) { - var xhr; - xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP'); - xhr.open('GET', url, true); - if ('overrideMimeType' in xhr) { - xhr.overrideMimeType('text/plain'); - } - xhr.onreadystatechange = function() { - var _ref; - if (xhr.readyState === 4) { - if ((_ref = xhr.status) === 0 || _ref === 200) { - CoffeeScript.run(xhr.responseText); - } else { - throw new Error("Could not load " + url); - } - if (callback) { - return callback(); - } - } - }; - return xhr.send(null); - }; - - runScripts = function() { - var coffees, execute, index, length, s, scripts; - scripts = document.getElementsByTagName('script'); - coffees = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = scripts.length; _i < _len; _i++) { - s = scripts[_i]; - if (s.type === 'text/coffeescript') { - _results.push(s); - } - } - return _results; - })(); - index = 0; - length = coffees.length; - (execute = function() { - var script; - script = coffees[index++]; - if ((script != null ? script.type : void 0) === 'text/coffeescript') { - if (script.src) { - return CoffeeScript.load(script.src, execute); - } else { - CoffeeScript.run(script.innerHTML); - return execute(); - } - } - })(); - return null; - }; - - if (window.addEventListener) { - addEventListener('DOMContentLoaded', runScripts, false); - } else { - attachEvent('onload', runScripts); - } - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js deleted file mode 100644 index 1523418f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/cake.js +++ /dev/null @@ -1,111 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks; - - fs = require('fs'); - - path = require('path'); - - helpers = require('./helpers'); - - optparse = require('./optparse'); - - CoffeeScript = require('./coffee-script'); - - tasks = {}; - - options = {}; - - switches = []; - - oparse = null; - - helpers.extend(global, { - task: function(name, description, action) { - var _ref; - if (!action) { - _ref = [description, action], action = _ref[0], description = _ref[1]; - } - return tasks[name] = { - name: name, - description: description, - action: action - }; - }, - option: function(letter, flag, description) { - return switches.push([letter, flag, description]); - }, - invoke: function(name) { - if (!tasks[name]) { - missingTask(name); - } - return tasks[name].action(options); - } - }); - - exports.run = function() { - var arg, args, _i, _len, _ref, _results; - global.__originalDirname = fs.realpathSync('.'); - process.chdir(cakefileDirectory(__originalDirname)); - args = process.argv.slice(2); - CoffeeScript.run(fs.readFileSync('Cakefile').toString(), { - filename: 'Cakefile' - }); - oparse = new optparse.OptionParser(switches); - if (!args.length) { - return printTasks(); - } - try { - options = oparse.parse(args); - } catch (e) { - return fatalError("" + e); - } - _ref = options["arguments"]; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - arg = _ref[_i]; - _results.push(invoke(arg)); - } - return _results; - }; - - printTasks = function() { - var cakefilePath, desc, name, relative, spaces, task; - relative = path.relative || path.resolve; - cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile'); - console.log("" + cakefilePath + " defines the following tasks:\n"); - for (name in tasks) { - task = tasks[name]; - spaces = 20 - name.length; - spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; - desc = task.description ? "# " + task.description : ''; - console.log("cake " + name + spaces + " " + desc); - } - if (switches.length) { - return console.log(oparse.help()); - } - }; - - fatalError = function(message) { - console.error(message + '\n'); - console.log('To see a list of all tasks/options, run "cake"'); - return process.exit(1); - }; - - missingTask = function(task) { - return fatalError("No such task: " + task); - }; - - cakefileDirectory = function(dir) { - var parent; - if (path.existsSync(path.join(dir, 'Cakefile'))) { - return dir; - } - parent = path.normalize(path.join(dir, '..')); - if (parent !== dir) { - return cakefileDirectory(parent); - } - throw new Error("Cakefile not found in " + (process.cwd())); - }; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js deleted file mode 100644 index c43fa497..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/coffee-script.js +++ /dev/null @@ -1,167 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref, - __hasProp = {}.hasOwnProperty; - - fs = require('fs'); - - path = require('path'); - - _ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED; - - parser = require('./parser').parser; - - vm = require('vm'); - - if (require.extensions) { - require.extensions['.coffee'] = function(module, filename) { - var content; - content = compile(fs.readFileSync(filename, 'utf8'), { - filename: filename - }); - return module._compile(content, filename); - }; - } else if (require.registerExtension) { - require.registerExtension('.coffee', function(content) { - return compile(content); - }); - } - - exports.VERSION = '1.3.3'; - - exports.RESERVED = RESERVED; - - exports.helpers = require('./helpers'); - - exports.compile = compile = function(code, options) { - var header, js, merge; - if (options == null) { - options = {}; - } - merge = exports.helpers.merge; - try { - js = (parser.parse(lexer.tokenize(code))).compile(options); - if (!options.header) { - return js; - } - } catch (err) { - if (options.filename) { - err.message = "In " + options.filename + ", " + err.message; - } - throw err; - } - header = "Generated by CoffeeScript " + this.VERSION; - return "// " + header + "\n" + js; - }; - - exports.tokens = function(code, options) { - return lexer.tokenize(code, options); - }; - - exports.nodes = function(source, options) { - if (typeof source === 'string') { - return parser.parse(lexer.tokenize(source, options)); - } else { - return parser.parse(source); - } - }; - - exports.run = function(code, options) { - var mainModule; - if (options == null) { - options = {}; - } - mainModule = require.main; - mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.'; - mainModule.moduleCache && (mainModule.moduleCache = {}); - mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename))); - if (path.extname(mainModule.filename) !== '.coffee' || require.extensions) { - return mainModule._compile(compile(code, options), mainModule.filename); - } else { - return mainModule._compile(code, mainModule.filename); - } - }; - - exports["eval"] = function(code, options) { - var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref1, _ref2, _require; - if (options == null) { - options = {}; - } - if (!(code = code.trim())) { - return; - } - Script = vm.Script; - if (Script) { - if (options.sandbox != null) { - if (options.sandbox instanceof Script.createContext().constructor) { - sandbox = options.sandbox; - } else { - sandbox = Script.createContext(); - _ref1 = options.sandbox; - for (k in _ref1) { - if (!__hasProp.call(_ref1, k)) continue; - v = _ref1[k]; - sandbox[k] = v; - } - } - sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox; - } else { - sandbox = global; - } - sandbox.__filename = options.filename || 'eval'; - sandbox.__dirname = path.dirname(sandbox.__filename); - if (!(sandbox !== global || sandbox.module || sandbox.require)) { - Module = require('module'); - sandbox.module = _module = new Module(options.modulename || 'eval'); - sandbox.require = _require = function(path) { - return Module._load(path, _module, true); - }; - _module.filename = sandbox.__filename; - _ref2 = Object.getOwnPropertyNames(require); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - r = _ref2[_i]; - if (r !== 'paths') { - _require[r] = require[r]; - } - } - _require.paths = _module.paths = Module._nodeModulePaths(process.cwd()); - _require.resolve = function(request) { - return Module._resolveFilename(request, _module); - }; - } - } - o = {}; - for (k in options) { - if (!__hasProp.call(options, k)) continue; - v = options[k]; - o[k] = v; - } - o.bare = true; - js = compile(code, o); - if (sandbox === global) { - return vm.runInThisContext(js); - } else { - return vm.runInContext(js, sandbox); - } - }; - - lexer = new Lexer; - - parser.lexer = { - lex: function() { - var tag, _ref1; - _ref1 = this.tokens[this.pos++] || [''], tag = _ref1[0], this.yytext = _ref1[1], this.yylineno = _ref1[2]; - return tag; - }, - setInput: function(tokens) { - this.tokens = tokens; - return this.pos = 0; - }, - upcomingInput: function() { - return ""; - } - }; - - parser.yy = require('./nodes'); - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js deleted file mode 100644 index e02da9fe..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/command.js +++ /dev/null @@ -1,500 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref; - - fs = require('fs'); - - path = require('path'); - - helpers = require('./helpers'); - - optparse = require('./optparse'); - - CoffeeScript = require('./coffee-script'); - - _ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec; - - EventEmitter = require('events').EventEmitter; - - helpers.extend(CoffeeScript, new EventEmitter); - - printLine = function(line) { - return process.stdout.write(line + '\n'); - }; - - printWarn = function(line) { - return process.stderr.write(line + '\n'); - }; - - hidden = function(file) { - return /^\.|~$/.test(file); - }; - - BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.'; - - SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']]; - - opts = {}; - - sources = []; - - sourceCode = []; - - notSources = {}; - - watchers = {}; - - optionParser = null; - - exports.run = function() { - var literals, source, _i, _len, _results; - parseOptions(); - if (opts.nodejs) { - return forkNode(); - } - if (opts.help) { - return usage(); - } - if (opts.version) { - return version(); - } - if (opts.require) { - loadRequires(); - } - if (opts.interactive) { - return require('./repl'); - } - if (opts.watch && !fs.watch) { - return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + "."); - } - if (opts.stdio) { - return compileStdio(); - } - if (opts["eval"]) { - return compileScript(null, sources[0]); - } - if (!sources.length) { - return require('./repl'); - } - literals = opts.run ? sources.splice(1) : []; - process.argv = process.argv.slice(0, 2).concat(literals); - process.argv[0] = 'coffee'; - process.execPath = require.main.filename; - _results = []; - for (_i = 0, _len = sources.length; _i < _len; _i++) { - source = sources[_i]; - _results.push(compilePath(source, true, path.normalize(source))); - } - return _results; - }; - - compilePath = function(source, topLevel, base) { - return fs.stat(source, function(err, stats) { - if (err && err.code !== 'ENOENT') { - throw err; - } - if ((err != null ? err.code : void 0) === 'ENOENT') { - if (topLevel && source.slice(-7) !== '.coffee') { - source = sources[sources.indexOf(source)] = "" + source + ".coffee"; - return compilePath(source, topLevel, base); - } - if (topLevel) { - console.error("File not found: " + source); - process.exit(1); - } - return; - } - if (stats.isDirectory()) { - if (opts.watch) { - watchDir(source, base); - } - return fs.readdir(source, function(err, files) { - var file, index, _ref1, _ref2; - if (err && err.code !== 'ENOENT') { - throw err; - } - if ((err != null ? err.code : void 0) === 'ENOENT') { - return; - } - index = sources.indexOf(source); - files = files.filter(function(file) { - return !hidden(file); - }); - [].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = files.length; _i < _len; _i++) { - file = files[_i]; - _results.push(path.join(source, file)); - } - return _results; - })())), _ref1; - [].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() { - return null; - }))), _ref2; - return files.forEach(function(file) { - return compilePath(path.join(source, file), false, base); - }); - }); - } else if (topLevel || path.extname(source) === '.coffee') { - if (opts.watch) { - watch(source, base); - } - return fs.readFile(source, function(err, code) { - if (err && err.code !== 'ENOENT') { - throw err; - } - if ((err != null ? err.code : void 0) === 'ENOENT') { - return; - } - return compileScript(source, code.toString(), base); - }); - } else { - notSources[source] = true; - return removeSource(source, base); - } - }); - }; - - compileScript = function(file, input, base) { - var o, options, t, task; - o = opts; - options = compileOptions(file); - try { - t = task = { - file: file, - input: input, - options: options - }; - CoffeeScript.emit('compile', task); - if (o.tokens) { - return printTokens(CoffeeScript.tokens(t.input)); - } else if (o.nodes) { - return printLine(CoffeeScript.nodes(t.input).toString().trim()); - } else if (o.run) { - return CoffeeScript.run(t.input, t.options); - } else if (o.join && t.file !== o.join) { - sourceCode[sources.indexOf(t.file)] = t.input; - return compileJoin(); - } else { - t.output = CoffeeScript.compile(t.input, t.options); - CoffeeScript.emit('success', task); - if (o.print) { - return printLine(t.output.trim()); - } else if (o.compile) { - return writeJs(t.file, t.output, base); - } else if (o.lint) { - return lint(t.file, t.output); - } - } - } catch (err) { - CoffeeScript.emit('failure', err, task); - if (CoffeeScript.listeners('failure').length) { - return; - } - if (o.watch) { - return printLine(err.message + '\x07'); - } - printWarn(err instanceof Error && err.stack || ("ERROR: " + err)); - return process.exit(1); - } - }; - - compileStdio = function() { - var code, stdin; - code = ''; - stdin = process.openStdin(); - stdin.on('data', function(buffer) { - if (buffer) { - return code += buffer.toString(); - } - }); - return stdin.on('end', function() { - return compileScript(null, code); - }); - }; - - joinTimeout = null; - - compileJoin = function() { - if (!opts.join) { - return; - } - if (!sourceCode.some(function(code) { - return code === null; - })) { - clearTimeout(joinTimeout); - return joinTimeout = wait(100, function() { - return compileScript(opts.join, sourceCode.join('\n'), opts.join); - }); - } - }; - - loadRequires = function() { - var realFilename, req, _i, _len, _ref1; - realFilename = module.filename; - module.filename = '.'; - _ref1 = opts.require; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - req = _ref1[_i]; - require(req); - } - return module.filename = realFilename; - }; - - watch = function(source, base) { - var compile, compileTimeout, prevStats, rewatch, watchErr, watcher; - prevStats = null; - compileTimeout = null; - watchErr = function(e) { - if (e.code === 'ENOENT') { - if (sources.indexOf(source) === -1) { - return; - } - try { - rewatch(); - return compile(); - } catch (e) { - removeSource(source, base, true); - return compileJoin(); - } - } else { - throw e; - } - }; - compile = function() { - clearTimeout(compileTimeout); - return compileTimeout = wait(25, function() { - return fs.stat(source, function(err, stats) { - if (err) { - return watchErr(err); - } - if (prevStats && stats.size === prevStats.size && stats.mtime.getTime() === prevStats.mtime.getTime()) { - return rewatch(); - } - prevStats = stats; - return fs.readFile(source, function(err, code) { - if (err) { - return watchErr(err); - } - compileScript(source, code.toString(), base); - return rewatch(); - }); - }); - }); - }; - try { - watcher = fs.watch(source, compile); - } catch (e) { - watchErr(e); - } - return rewatch = function() { - if (watcher != null) { - watcher.close(); - } - return watcher = fs.watch(source, compile); - }; - }; - - watchDir = function(source, base) { - var readdirTimeout, watcher; - readdirTimeout = null; - try { - return watcher = fs.watch(source, function() { - clearTimeout(readdirTimeout); - return readdirTimeout = wait(25, function() { - return fs.readdir(source, function(err, files) { - var file, _i, _len, _results; - if (err) { - if (err.code !== 'ENOENT') { - throw err; - } - watcher.close(); - return unwatchDir(source, base); - } - _results = []; - for (_i = 0, _len = files.length; _i < _len; _i++) { - file = files[_i]; - if (!(!hidden(file) && !notSources[file])) { - continue; - } - file = path.join(source, file); - if (sources.some(function(s) { - return s.indexOf(file) >= 0; - })) { - continue; - } - sources.push(file); - sourceCode.push(null); - _results.push(compilePath(file, false, base)); - } - return _results; - }); - }); - }); - } catch (e) { - if (e.code !== 'ENOENT') { - throw e; - } - } - }; - - unwatchDir = function(source, base) { - var file, prevSources, toRemove, _i, _len; - prevSources = sources.slice(0); - toRemove = (function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = sources.length; _i < _len; _i++) { - file = sources[_i]; - if (file.indexOf(source) >= 0) { - _results.push(file); - } - } - return _results; - })(); - for (_i = 0, _len = toRemove.length; _i < _len; _i++) { - file = toRemove[_i]; - removeSource(file, base, true); - } - if (!sources.some(function(s, i) { - return prevSources[i] !== s; - })) { - return; - } - return compileJoin(); - }; - - removeSource = function(source, base, removeJs) { - var index, jsPath; - index = sources.indexOf(source); - sources.splice(index, 1); - sourceCode.splice(index, 1); - if (removeJs && !opts.join) { - jsPath = outputPath(source, base); - return path.exists(jsPath, function(exists) { - if (exists) { - return fs.unlink(jsPath, function(err) { - if (err && err.code !== 'ENOENT') { - throw err; - } - return timeLog("removed " + source); - }); - } - }); - } - }; - - outputPath = function(source, base) { - var baseDir, dir, filename, srcDir; - filename = path.basename(source, path.extname(source)) + '.js'; - srcDir = path.dirname(source); - baseDir = base === '.' ? srcDir : srcDir.substring(base.length); - dir = opts.output ? path.join(opts.output, baseDir) : srcDir; - return path.join(dir, filename); - }; - - writeJs = function(source, js, base) { - var compile, jsDir, jsPath; - jsPath = outputPath(source, base); - jsDir = path.dirname(jsPath); - compile = function() { - if (js.length <= 0) { - js = ' '; - } - return fs.writeFile(jsPath, js, function(err) { - if (err) { - return printLine(err.message); - } else if (opts.compile && opts.watch) { - return timeLog("compiled " + source); - } - }); - }; - return path.exists(jsDir, function(exists) { - if (exists) { - return compile(); - } else { - return exec("mkdir -p " + jsDir, compile); - } - }); - }; - - wait = function(milliseconds, func) { - return setTimeout(func, milliseconds); - }; - - timeLog = function(message) { - return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message); - }; - - lint = function(file, js) { - var conf, jsl, printIt; - printIt = function(buffer) { - return printLine(file + ':\t' + buffer.toString().trim()); - }; - conf = __dirname + '/../../extras/jsl.conf'; - jsl = spawn('jsl', ['-nologo', '-stdin', '-conf', conf]); - jsl.stdout.on('data', printIt); - jsl.stderr.on('data', printIt); - jsl.stdin.write(js); - return jsl.stdin.end(); - }; - - printTokens = function(tokens) { - var strings, tag, token, value; - strings = (function() { - var _i, _len, _ref1, _results; - _results = []; - for (_i = 0, _len = tokens.length; _i < _len; _i++) { - token = tokens[_i]; - _ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1]; - _results.push("[" + tag + " " + value + "]"); - } - return _results; - })(); - return printLine(strings.join(' ')); - }; - - parseOptions = function() { - var i, o, source, _i, _len; - optionParser = new optparse.OptionParser(SWITCHES, BANNER); - o = opts = optionParser.parse(process.argv.slice(2)); - o.compile || (o.compile = !!o.output); - o.run = !(o.compile || o.print || o.lint); - o.print = !!(o.print || (o["eval"] || o.stdio && o.compile)); - sources = o["arguments"]; - for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) { - source = sources[i]; - sourceCode[i] = null; - } - }; - - compileOptions = function(filename) { - return { - filename: filename, - bare: opts.bare, - header: opts.compile - }; - }; - - forkNode = function() { - var args, nodeArgs; - nodeArgs = opts.nodejs.split(/\s+/); - args = process.argv.slice(1); - args.splice(args.indexOf('--nodejs'), 2); - return spawn(process.execPath, nodeArgs.concat(args), { - cwd: process.cwd(), - env: process.env, - customFds: [0, 1, 2] - }); - }; - - usage = function() { - return printLine((new optparse.OptionParser(SWITCHES, BANNER)).help()); - }; - - version = function() { - return printLine("CoffeeScript version " + CoffeeScript.VERSION); - }; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js deleted file mode 100644 index 56621388..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/grammar.js +++ /dev/null @@ -1,606 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; - - Parser = require('jison').Parser; - - unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/; - - o = function(patternString, action, options) { - var match; - patternString = patternString.replace(/\s{2,}/g, ' '); - if (!action) { - return [patternString, '$$ = $1;', options]; - } - action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())"; - action = action.replace(/\bnew /g, '$&yy.'); - action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&'); - return [patternString, "$$ = " + action + ";", options]; - }; - - grammar = { - Root: [ - o('', function() { - return new Block; - }), o('Body'), o('Block TERMINATOR') - ], - Body: [ - o('Line', function() { - return Block.wrap([$1]); - }), o('Body TERMINATOR Line', function() { - return $1.push($3); - }), o('Body TERMINATOR') - ], - Line: [o('Expression'), o('Statement')], - Statement: [ - o('Return'), o('Comment'), o('STATEMENT', function() { - return new Literal($1); - }) - ], - Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')], - Block: [ - o('INDENT OUTDENT', function() { - return new Block; - }), o('INDENT Body OUTDENT', function() { - return $2; - }) - ], - Identifier: [ - o('IDENTIFIER', function() { - return new Literal($1); - }) - ], - AlphaNumeric: [ - o('NUMBER', function() { - return new Literal($1); - }), o('STRING', function() { - return new Literal($1); - }) - ], - Literal: [ - o('AlphaNumeric'), o('JS', function() { - return new Literal($1); - }), o('REGEX', function() { - return new Literal($1); - }), o('DEBUGGER', function() { - return new Literal($1); - }), o('UNDEFINED', function() { - return new Undefined; - }), o('NULL', function() { - return new Null; - }), o('BOOL', function() { - return new Bool($1); - }) - ], - Assign: [ - o('Assignable = Expression', function() { - return new Assign($1, $3); - }), o('Assignable = TERMINATOR Expression', function() { - return new Assign($1, $4); - }), o('Assignable = INDENT Expression OUTDENT', function() { - return new Assign($1, $4); - }) - ], - AssignObj: [ - o('ObjAssignable', function() { - return new Value($1); - }), o('ObjAssignable : Expression', function() { - return new Assign(new Value($1), $3, 'object'); - }), o('ObjAssignable :\ - INDENT Expression OUTDENT', function() { - return new Assign(new Value($1), $4, 'object'); - }), o('Comment') - ], - ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')], - Return: [ - o('RETURN Expression', function() { - return new Return($2); - }), o('RETURN', function() { - return new Return; - }) - ], - Comment: [ - o('HERECOMMENT', function() { - return new Comment($1); - }) - ], - Code: [ - o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() { - return new Code($2, $5, $4); - }), o('FuncGlyph Block', function() { - return new Code([], $2, $1); - }) - ], - FuncGlyph: [ - o('->', function() { - return 'func'; - }), o('=>', function() { - return 'boundfunc'; - }) - ], - OptComma: [o(''), o(',')], - ParamList: [ - o('', function() { - return []; - }), o('Param', function() { - return [$1]; - }), o('ParamList , Param', function() { - return $1.concat($3); - }), o('ParamList OptComma TERMINATOR Param', function() { - return $1.concat($4); - }), o('ParamList OptComma INDENT ParamList OptComma OUTDENT', function() { - return $1.concat($4); - }) - ], - Param: [ - o('ParamVar', function() { - return new Param($1); - }), o('ParamVar ...', function() { - return new Param($1, null, true); - }), o('ParamVar = Expression', function() { - return new Param($1, $3); - }) - ], - ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')], - Splat: [ - o('Expression ...', function() { - return new Splat($1); - }) - ], - SimpleAssignable: [ - o('Identifier', function() { - return new Value($1); - }), o('Value Accessor', function() { - return $1.add($2); - }), o('Invocation Accessor', function() { - return new Value($1, [].concat($2)); - }), o('ThisProperty') - ], - Assignable: [ - o('SimpleAssignable'), o('Array', function() { - return new Value($1); - }), o('Object', function() { - return new Value($1); - }) - ], - Value: [ - o('Assignable'), o('Literal', function() { - return new Value($1); - }), o('Parenthetical', function() { - return new Value($1); - }), o('Range', function() { - return new Value($1); - }), o('This') - ], - Accessor: [ - o('. Identifier', function() { - return new Access($2); - }), o('?. Identifier', function() { - return new Access($2, 'soak'); - }), o(':: Identifier', function() { - return [new Access(new Literal('prototype')), new Access($2)]; - }), o('::', function() { - return new Access(new Literal('prototype')); - }), o('Index') - ], - Index: [ - o('INDEX_START IndexValue INDEX_END', function() { - return $2; - }), o('INDEX_SOAK Index', function() { - return extend($2, { - soak: true - }); - }) - ], - IndexValue: [ - o('Expression', function() { - return new Index($1); - }), o('Slice', function() { - return new Slice($1); - }) - ], - Object: [ - o('{ AssignList OptComma }', function() { - return new Obj($2, $1.generated); - }) - ], - AssignList: [ - o('', function() { - return []; - }), o('AssignObj', function() { - return [$1]; - }), o('AssignList , AssignObj', function() { - return $1.concat($3); - }), o('AssignList OptComma TERMINATOR AssignObj', function() { - return $1.concat($4); - }), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() { - return $1.concat($4); - }) - ], - Class: [ - o('CLASS', function() { - return new Class; - }), o('CLASS Block', function() { - return new Class(null, null, $2); - }), o('CLASS EXTENDS Expression', function() { - return new Class(null, $3); - }), o('CLASS EXTENDS Expression Block', function() { - return new Class(null, $3, $4); - }), o('CLASS SimpleAssignable', function() { - return new Class($2); - }), o('CLASS SimpleAssignable Block', function() { - return new Class($2, null, $3); - }), o('CLASS SimpleAssignable EXTENDS Expression', function() { - return new Class($2, $4); - }), o('CLASS SimpleAssignable EXTENDS Expression Block', function() { - return new Class($2, $4, $5); - }) - ], - Invocation: [ - o('Value OptFuncExist Arguments', function() { - return new Call($1, $3, $2); - }), o('Invocation OptFuncExist Arguments', function() { - return new Call($1, $3, $2); - }), o('SUPER', function() { - return new Call('super', [new Splat(new Literal('arguments'))]); - }), o('SUPER Arguments', function() { - return new Call('super', $2); - }) - ], - OptFuncExist: [ - o('', function() { - return false; - }), o('FUNC_EXIST', function() { - return true; - }) - ], - Arguments: [ - o('CALL_START CALL_END', function() { - return []; - }), o('CALL_START ArgList OptComma CALL_END', function() { - return $2; - }) - ], - This: [ - o('THIS', function() { - return new Value(new Literal('this')); - }), o('@', function() { - return new Value(new Literal('this')); - }) - ], - ThisProperty: [ - o('@ Identifier', function() { - return new Value(new Literal('this'), [new Access($2)], 'this'); - }) - ], - Array: [ - o('[ ]', function() { - return new Arr([]); - }), o('[ ArgList OptComma ]', function() { - return new Arr($2); - }) - ], - RangeDots: [ - o('..', function() { - return 'inclusive'; - }), o('...', function() { - return 'exclusive'; - }) - ], - Range: [ - o('[ Expression RangeDots Expression ]', function() { - return new Range($2, $4, $3); - }) - ], - Slice: [ - o('Expression RangeDots Expression', function() { - return new Range($1, $3, $2); - }), o('Expression RangeDots', function() { - return new Range($1, null, $2); - }), o('RangeDots Expression', function() { - return new Range(null, $2, $1); - }), o('RangeDots', function() { - return new Range(null, null, $1); - }) - ], - ArgList: [ - o('Arg', function() { - return [$1]; - }), o('ArgList , Arg', function() { - return $1.concat($3); - }), o('ArgList OptComma TERMINATOR Arg', function() { - return $1.concat($4); - }), o('INDENT ArgList OptComma OUTDENT', function() { - return $2; - }), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() { - return $1.concat($4); - }) - ], - Arg: [o('Expression'), o('Splat')], - SimpleArgs: [ - o('Expression'), o('SimpleArgs , Expression', function() { - return [].concat($1, $3); - }) - ], - Try: [ - o('TRY Block', function() { - return new Try($2); - }), o('TRY Block Catch', function() { - return new Try($2, $3[0], $3[1]); - }), o('TRY Block FINALLY Block', function() { - return new Try($2, null, null, $4); - }), o('TRY Block Catch FINALLY Block', function() { - return new Try($2, $3[0], $3[1], $5); - }) - ], - Catch: [ - o('CATCH Identifier Block', function() { - return [$2, $3]; - }) - ], - Throw: [ - o('THROW Expression', function() { - return new Throw($2); - }) - ], - Parenthetical: [ - o('( Body )', function() { - return new Parens($2); - }), o('( INDENT Body OUTDENT )', function() { - return new Parens($3); - }) - ], - WhileSource: [ - o('WHILE Expression', function() { - return new While($2); - }), o('WHILE Expression WHEN Expression', function() { - return new While($2, { - guard: $4 - }); - }), o('UNTIL Expression', function() { - return new While($2, { - invert: true - }); - }), o('UNTIL Expression WHEN Expression', function() { - return new While($2, { - invert: true, - guard: $4 - }); - }) - ], - While: [ - o('WhileSource Block', function() { - return $1.addBody($2); - }), o('Statement WhileSource', function() { - return $2.addBody(Block.wrap([$1])); - }), o('Expression WhileSource', function() { - return $2.addBody(Block.wrap([$1])); - }), o('Loop', function() { - return $1; - }) - ], - Loop: [ - o('LOOP Block', function() { - return new While(new Literal('true')).addBody($2); - }), o('LOOP Expression', function() { - return new While(new Literal('true')).addBody(Block.wrap([$2])); - }) - ], - For: [ - o('Statement ForBody', function() { - return new For($1, $2); - }), o('Expression ForBody', function() { - return new For($1, $2); - }), o('ForBody Block', function() { - return new For($2, $1); - }) - ], - ForBody: [ - o('FOR Range', function() { - return { - source: new Value($2) - }; - }), o('ForStart ForSource', function() { - $2.own = $1.own; - $2.name = $1[0]; - $2.index = $1[1]; - return $2; - }) - ], - ForStart: [ - o('FOR ForVariables', function() { - return $2; - }), o('FOR OWN ForVariables', function() { - $3.own = true; - return $3; - }) - ], - ForValue: [ - o('Identifier'), o('ThisProperty'), o('Array', function() { - return new Value($1); - }), o('Object', function() { - return new Value($1); - }) - ], - ForVariables: [ - o('ForValue', function() { - return [$1]; - }), o('ForValue , ForValue', function() { - return [$1, $3]; - }) - ], - ForSource: [ - o('FORIN Expression', function() { - return { - source: $2 - }; - }), o('FOROF Expression', function() { - return { - source: $2, - object: true - }; - }), o('FORIN Expression WHEN Expression', function() { - return { - source: $2, - guard: $4 - }; - }), o('FOROF Expression WHEN Expression', function() { - return { - source: $2, - guard: $4, - object: true - }; - }), o('FORIN Expression BY Expression', function() { - return { - source: $2, - step: $4 - }; - }), o('FORIN Expression WHEN Expression BY Expression', function() { - return { - source: $2, - guard: $4, - step: $6 - }; - }), o('FORIN Expression BY Expression WHEN Expression', function() { - return { - source: $2, - step: $4, - guard: $6 - }; - }) - ], - Switch: [ - o('SWITCH Expression INDENT Whens OUTDENT', function() { - return new Switch($2, $4); - }), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() { - return new Switch($2, $4, $6); - }), o('SWITCH INDENT Whens OUTDENT', function() { - return new Switch(null, $3); - }), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() { - return new Switch(null, $3, $5); - }) - ], - Whens: [ - o('When'), o('Whens When', function() { - return $1.concat($2); - }) - ], - When: [ - o('LEADING_WHEN SimpleArgs Block', function() { - return [[$2, $3]]; - }), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() { - return [[$2, $3]]; - }) - ], - IfBlock: [ - o('IF Expression Block', function() { - return new If($2, $3, { - type: $1 - }); - }), o('IfBlock ELSE IF Expression Block', function() { - return $1.addElse(new If($4, $5, { - type: $3 - })); - }) - ], - If: [ - o('IfBlock'), o('IfBlock ELSE Block', function() { - return $1.addElse($3); - }), o('Statement POST_IF Expression', function() { - return new If($3, Block.wrap([$1]), { - type: $2, - statement: true - }); - }), o('Expression POST_IF Expression', function() { - return new If($3, Block.wrap([$1]), { - type: $2, - statement: true - }); - }) - ], - Operation: [ - o('UNARY Expression', function() { - return new Op($1, $2); - }), o('- Expression', (function() { - return new Op('-', $2); - }), { - prec: 'UNARY' - }), o('+ Expression', (function() { - return new Op('+', $2); - }), { - prec: 'UNARY' - }), o('-- SimpleAssignable', function() { - return new Op('--', $2); - }), o('++ SimpleAssignable', function() { - return new Op('++', $2); - }), o('SimpleAssignable --', function() { - return new Op('--', $1, null, true); - }), o('SimpleAssignable ++', function() { - return new Op('++', $1, null, true); - }), o('Expression ?', function() { - return new Existence($1); - }), o('Expression + Expression', function() { - return new Op('+', $1, $3); - }), o('Expression - Expression', function() { - return new Op('-', $1, $3); - }), o('Expression MATH Expression', function() { - return new Op($2, $1, $3); - }), o('Expression SHIFT Expression', function() { - return new Op($2, $1, $3); - }), o('Expression COMPARE Expression', function() { - return new Op($2, $1, $3); - }), o('Expression LOGIC Expression', function() { - return new Op($2, $1, $3); - }), o('Expression RELATION Expression', function() { - if ($2.charAt(0) === '!') { - return new Op($2.slice(1), $1, $3).invert(); - } else { - return new Op($2, $1, $3); - } - }), o('SimpleAssignable COMPOUND_ASSIGN\ - Expression', function() { - return new Assign($1, $3, $2); - }), o('SimpleAssignable COMPOUND_ASSIGN\ - INDENT Expression OUTDENT', function() { - return new Assign($1, $4, $2); - }), o('SimpleAssignable EXTENDS Expression', function() { - return new Extends($1, $3); - }) - ] - }; - - operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']]; - - tokens = []; - - for (name in grammar) { - alternatives = grammar[name]; - grammar[name] = (function() { - var _i, _j, _len, _len1, _ref, _results; - _results = []; - for (_i = 0, _len = alternatives.length; _i < _len; _i++) { - alt = alternatives[_i]; - _ref = alt[0].split(' '); - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - token = _ref[_j]; - if (!grammar[token]) { - tokens.push(token); - } - } - if (name === 'Root') { - alt[1] = "return " + alt[1]; - } - _results.push(alt); - } - return _results; - })(); - } - - exports.parser = new Parser({ - tokens: tokens.join(' '), - bnf: grammar, - operators: operators.reverse(), - startSymbol: 'Root' - }); - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js deleted file mode 100644 index b0a997b8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/helpers.js +++ /dev/null @@ -1,77 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var extend, flatten; - - exports.starts = function(string, literal, start) { - return literal === string.substr(start, literal.length); - }; - - exports.ends = function(string, literal, back) { - var len; - len = literal.length; - return literal === string.substr(string.length - len - (back || 0), len); - }; - - exports.compact = function(array) { - var item, _i, _len, _results; - _results = []; - for (_i = 0, _len = array.length; _i < _len; _i++) { - item = array[_i]; - if (item) { - _results.push(item); - } - } - return _results; - }; - - exports.count = function(string, substr) { - var num, pos; - num = pos = 0; - if (!substr.length) { - return 1 / 0; - } - while (pos = 1 + string.indexOf(substr, pos)) { - num++; - } - return num; - }; - - exports.merge = function(options, overrides) { - return extend(extend({}, options), overrides); - }; - - extend = exports.extend = function(object, properties) { - var key, val; - for (key in properties) { - val = properties[key]; - object[key] = val; - } - return object; - }; - - exports.flatten = flatten = function(array) { - var element, flattened, _i, _len; - flattened = []; - for (_i = 0, _len = array.length; _i < _len; _i++) { - element = array[_i]; - if (element instanceof Array) { - flattened = flattened.concat(flatten(element)); - } else { - flattened.push(element); - } - } - return flattened; - }; - - exports.del = function(obj, key) { - var val; - val = obj[key]; - delete obj[key]; - return val; - }; - - exports.last = function(array, back) { - return array[array.length - (back || 0) - 1]; - }; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js deleted file mode 100644 index d344c41a..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/index.js +++ /dev/null @@ -1,11 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var key, val, _ref; - - _ref = require('./coffee-script'); - for (key in _ref) { - val = _ref[key]; - exports[key] = val; - } - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js deleted file mode 100644 index f80a4433..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/lexer.js +++ /dev/null @@ -1,788 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref1, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES; - - _ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last; - - exports.Lexer = Lexer = (function() { - - function Lexer() {} - - Lexer.prototype.tokenize = function(code, opts) { - var i, tag; - if (opts == null) { - opts = {}; - } - if (WHITESPACE.test(code)) { - code = "\n" + code; - } - code = code.replace(/\r/g, '').replace(TRAILING_SPACES, ''); - this.code = code; - this.line = opts.line || 0; - this.indent = 0; - this.indebt = 0; - this.outdebt = 0; - this.indents = []; - this.ends = []; - this.tokens = []; - i = 0; - while (this.chunk = code.slice(i)) { - i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); - } - this.closeIndentation(); - if (tag = this.ends.pop()) { - this.error("missing " + tag); - } - if (opts.rewrite === false) { - return this.tokens; - } - return (new Rewriter).rewrite(this.tokens); - }; - - Lexer.prototype.identifierToken = function() { - var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3; - if (!(match = IDENTIFIER.exec(this.chunk))) { - return 0; - } - input = match[0], id = match[1], colon = match[2]; - if (id === 'own' && this.tag() === 'FOR') { - this.token('OWN', id); - return id.length; - } - forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::') || !prev.spaced && prev[0] === '@'); - tag = 'IDENTIFIER'; - if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) { - tag = id.toUpperCase(); - if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) { - tag = 'LEADING_WHEN'; - } else if (tag === 'FOR') { - this.seenFor = true; - } else if (tag === 'UNLESS') { - tag = 'IF'; - } else if (__indexOf.call(UNARY, tag) >= 0) { - tag = 'UNARY'; - } else if (__indexOf.call(RELATION, tag) >= 0) { - if (tag !== 'INSTANCEOF' && this.seenFor) { - tag = 'FOR' + tag; - this.seenFor = false; - } else { - tag = 'RELATION'; - if (this.value() === '!') { - this.tokens.pop(); - id = '!' + id; - } - } - } - } - if (__indexOf.call(JS_FORBIDDEN, id) >= 0) { - if (forcedIdentifier) { - tag = 'IDENTIFIER'; - id = new String(id); - id.reserved = true; - } else if (__indexOf.call(RESERVED, id) >= 0) { - this.error("reserved word \"" + id + "\""); - } - } - if (!forcedIdentifier) { - if (__indexOf.call(COFFEE_ALIASES, id) >= 0) { - id = COFFEE_ALIAS_MAP[id]; - } - tag = (function() { - switch (id) { - case '!': - return 'UNARY'; - case '==': - case '!=': - return 'COMPARE'; - case '&&': - case '||': - return 'LOGIC'; - case 'true': - case 'false': - return 'BOOL'; - case 'break': - case 'continue': - return 'STATEMENT'; - default: - return tag; - } - })(); - } - this.token(tag, id); - if (colon) { - this.token(':', ':'); - } - return input.length; - }; - - Lexer.prototype.numberToken = function() { - var binaryLiteral, lexedLength, match, number, octalLiteral; - if (!(match = NUMBER.exec(this.chunk))) { - return 0; - } - number = match[0]; - if (/^0[BOX]/.test(number)) { - this.error("radix prefix '" + number + "' must be lowercase"); - } else if (/E/.test(number) && !/^0x/.test(number)) { - this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'"); - } else if (/^0\d*[89]/.test(number)) { - this.error("decimal literal '" + number + "' must not be prefixed with '0'"); - } else if (/^0\d+/.test(number)) { - this.error("octal literal '" + number + "' must be prefixed with '0o'"); - } - lexedLength = number.length; - if (octalLiteral = /^0o([0-7]+)/.exec(number)) { - number = '0x' + (parseInt(octalLiteral[1], 8)).toString(16); - } - if (binaryLiteral = /^0b([01]+)/.exec(number)) { - number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16); - } - this.token('NUMBER', number); - return lexedLength; - }; - - Lexer.prototype.stringToken = function() { - var match, octalEsc, string; - switch (this.chunk.charAt(0)) { - case "'": - if (!(match = SIMPLESTR.exec(this.chunk))) { - return 0; - } - this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n')); - break; - case '"': - if (!(string = this.balancedString(this.chunk, '"'))) { - return 0; - } - if (0 < string.indexOf('#{', 1)) { - this.interpolateString(string.slice(1, -1)); - } else { - this.token('STRING', this.escapeLines(string)); - } - break; - default: - return 0; - } - if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) { - this.error("octal escape sequences " + string + " are not allowed"); - } - this.line += count(string, '\n'); - return string.length; - }; - - Lexer.prototype.heredocToken = function() { - var doc, heredoc, match, quote; - if (!(match = HEREDOC.exec(this.chunk))) { - return 0; - } - heredoc = match[0]; - quote = heredoc.charAt(0); - doc = this.sanitizeHeredoc(match[2], { - quote: quote, - indent: null - }); - if (quote === '"' && 0 <= doc.indexOf('#{')) { - this.interpolateString(doc, { - heredoc: true - }); - } else { - this.token('STRING', this.makeString(doc, quote, true)); - } - this.line += count(heredoc, '\n'); - return heredoc.length; - }; - - Lexer.prototype.commentToken = function() { - var comment, here, match; - if (!(match = this.chunk.match(COMMENT))) { - return 0; - } - comment = match[0], here = match[1]; - if (here) { - this.token('HERECOMMENT', this.sanitizeHeredoc(here, { - herecomment: true, - indent: Array(this.indent + 1).join(' ') - })); - } - this.line += count(comment, '\n'); - return comment.length; - }; - - Lexer.prototype.jsToken = function() { - var match, script; - if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) { - return 0; - } - this.token('JS', (script = match[0]).slice(1, -1)); - return script.length; - }; - - Lexer.prototype.regexToken = function() { - var flags, length, match, prev, regex, _ref2, _ref3; - if (this.chunk.charAt(0) !== '/') { - return 0; - } - if (match = HEREGEX.exec(this.chunk)) { - length = this.heregexToken(match); - this.line += count(match[0], '\n'); - return length; - } - prev = last(this.tokens); - if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) { - return 0; - } - if (!(match = REGEX.exec(this.chunk))) { - return 0; - } - _ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2]; - if (regex.slice(0, 2) === '/*') { - this.error('regular expressions cannot begin with `*`'); - } - if (regex === '//') { - regex = '/(?:)/'; - } - this.token('REGEX', "" + regex + flags); - return match.length; - }; - - Lexer.prototype.heregexToken = function(match) { - var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5; - heregex = match[0], body = match[1], flags = match[2]; - if (0 > body.indexOf('#{')) { - re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/'); - if (re.match(/^\*/)) { - this.error('regular expressions cannot begin with `*`'); - } - this.token('REGEX', "/" + (re || '(?:)') + "/" + flags); - return heregex.length; - } - this.token('IDENTIFIER', 'RegExp'); - this.tokens.push(['CALL_START', '(']); - tokens = []; - _ref2 = this.interpolateString(body, { - regex: true - }); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - _ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1]; - if (tag === 'TOKENS') { - tokens.push.apply(tokens, value); - } else { - if (!(value = value.replace(HEREGEX_OMIT, ''))) { - continue; - } - value = value.replace(/\\/g, '\\\\'); - tokens.push(['STRING', this.makeString(value, '"', true)]); - } - tokens.push(['+', '+']); - } - tokens.pop(); - if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') { - this.tokens.push(['STRING', '""'], ['+', '+']); - } - (_ref5 = this.tokens).push.apply(_ref5, tokens); - if (flags) { - this.tokens.push([',', ','], ['STRING', '"' + flags + '"']); - } - this.token(')', ')'); - return heregex.length; - }; - - Lexer.prototype.lineToken = function() { - var diff, indent, match, noNewlines, prev, size; - if (!(match = MULTI_DENT.exec(this.chunk))) { - return 0; - } - indent = match[0]; - this.line += count(indent, '\n'); - this.seenFor = false; - prev = last(this.tokens, 1); - size = indent.length - 1 - indent.lastIndexOf('\n'); - noNewlines = this.unfinished(); - if (size - this.indebt === this.indent) { - if (noNewlines) { - this.suppressNewlines(); - } else { - this.newlineToken(); - } - return indent.length; - } - if (size > this.indent) { - if (noNewlines) { - this.indebt = size - this.indent; - this.suppressNewlines(); - return indent.length; - } - diff = size - this.indent + this.outdebt; - this.token('INDENT', diff); - this.indents.push(diff); - this.ends.push('OUTDENT'); - this.outdebt = this.indebt = 0; - } else { - this.indebt = 0; - this.outdentToken(this.indent - size, noNewlines); - } - this.indent = size; - return indent.length; - }; - - Lexer.prototype.outdentToken = function(moveOut, noNewlines) { - var dent, len; - while (moveOut > 0) { - len = this.indents.length - 1; - if (this.indents[len] === void 0) { - moveOut = 0; - } else if (this.indents[len] === this.outdebt) { - moveOut -= this.outdebt; - this.outdebt = 0; - } else if (this.indents[len] < this.outdebt) { - this.outdebt -= this.indents[len]; - moveOut -= this.indents[len]; - } else { - dent = this.indents.pop() - this.outdebt; - moveOut -= dent; - this.outdebt = 0; - this.pair('OUTDENT'); - this.token('OUTDENT', dent); - } - } - if (dent) { - this.outdebt -= moveOut; - } - while (this.value() === ';') { - this.tokens.pop(); - } - if (!(this.tag() === 'TERMINATOR' || noNewlines)) { - this.token('TERMINATOR', '\n'); - } - return this; - }; - - Lexer.prototype.whitespaceToken = function() { - var match, nline, prev; - if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) { - return 0; - } - prev = last(this.tokens); - if (prev) { - prev[match ? 'spaced' : 'newLine'] = true; - } - if (match) { - return match[0].length; - } else { - return 0; - } - }; - - Lexer.prototype.newlineToken = function() { - while (this.value() === ';') { - this.tokens.pop(); - } - if (this.tag() !== 'TERMINATOR') { - this.token('TERMINATOR', '\n'); - } - return this; - }; - - Lexer.prototype.suppressNewlines = function() { - if (this.value() === '\\') { - this.tokens.pop(); - } - return this; - }; - - Lexer.prototype.literalToken = function() { - var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5; - if (match = OPERATOR.exec(this.chunk)) { - value = match[0]; - if (CODE.test(value)) { - this.tagParameters(); - } - } else { - value = this.chunk.charAt(0); - } - tag = value; - prev = last(this.tokens); - if (value === '=' && prev) { - if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) { - this.error("reserved word \"" + (this.value()) + "\" can't be assigned"); - } - if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') { - prev[0] = 'COMPOUND_ASSIGN'; - prev[1] += '='; - return value.length; - } - } - if (value === ';') { - this.seenFor = false; - tag = 'TERMINATOR'; - } else if (__indexOf.call(MATH, value) >= 0) { - tag = 'MATH'; - } else if (__indexOf.call(COMPARE, value) >= 0) { - tag = 'COMPARE'; - } else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) { - tag = 'COMPOUND_ASSIGN'; - } else if (__indexOf.call(UNARY, value) >= 0) { - tag = 'UNARY'; - } else if (__indexOf.call(SHIFT, value) >= 0) { - tag = 'SHIFT'; - } else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) { - tag = 'LOGIC'; - } else if (prev && !prev.spaced) { - if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) { - if (prev[0] === '?') { - prev[0] = 'FUNC_EXIST'; - } - tag = 'CALL_START'; - } else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) { - tag = 'INDEX_START'; - switch (prev[0]) { - case '?': - prev[0] = 'INDEX_SOAK'; - } - } - } - switch (value) { - case '(': - case '{': - case '[': - this.ends.push(INVERSES[value]); - break; - case ')': - case '}': - case ']': - this.pair(value); - } - this.token(tag, value); - return value.length; - }; - - Lexer.prototype.sanitizeHeredoc = function(doc, options) { - var attempt, herecomment, indent, match, _ref2; - indent = options.indent, herecomment = options.herecomment; - if (herecomment) { - if (HEREDOC_ILLEGAL.test(doc)) { - this.error("block comment cannot contain \"*/\", starting"); - } - if (doc.indexOf('\n') <= 0) { - return doc; - } - } else { - while (match = HEREDOC_INDENT.exec(doc)) { - attempt = match[1]; - if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) { - indent = attempt; - } - } - } - if (indent) { - doc = doc.replace(RegExp("\\n" + indent, "g"), '\n'); - } - if (!herecomment) { - doc = doc.replace(/^\n/, ''); - } - return doc; - }; - - Lexer.prototype.tagParameters = function() { - var i, stack, tok, tokens; - if (this.tag() !== ')') { - return this; - } - stack = []; - tokens = this.tokens; - i = tokens.length; - tokens[--i][0] = 'PARAM_END'; - while (tok = tokens[--i]) { - switch (tok[0]) { - case ')': - stack.push(tok); - break; - case '(': - case 'CALL_START': - if (stack.length) { - stack.pop(); - } else if (tok[0] === '(') { - tok[0] = 'PARAM_START'; - return this; - } else { - return this; - } - } - } - return this; - }; - - Lexer.prototype.closeIndentation = function() { - return this.outdentToken(this.indent); - }; - - Lexer.prototype.balancedString = function(str, end) { - var continueCount, i, letter, match, prev, stack, _i, _ref2; - continueCount = 0; - stack = [end]; - for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) { - if (continueCount) { - --continueCount; - continue; - } - switch (letter = str.charAt(i)) { - case '\\': - ++continueCount; - continue; - case end: - stack.pop(); - if (!stack.length) { - return str.slice(0, i + 1 || 9e9); - } - end = stack[stack.length - 1]; - continue; - } - if (end === '}' && (letter === '"' || letter === "'")) { - stack.push(end = letter); - } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) { - continueCount += match[0].length - 1; - } else if (end === '}' && letter === '{') { - stack.push(end = '}'); - } else if (end === '"' && prev === '#' && letter === '{') { - stack.push(end = '}'); - } - prev = letter; - } - return this.error("missing " + (stack.pop()) + ", starting"); - }; - - Lexer.prototype.interpolateString = function(str, options) { - var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4; - if (options == null) { - options = {}; - } - heredoc = options.heredoc, regex = options.regex; - tokens = []; - pi = 0; - i = -1; - while (letter = str.charAt(i += 1)) { - if (letter === '\\') { - i += 1; - continue; - } - if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) { - continue; - } - if (pi < i) { - tokens.push(['NEOSTRING', str.slice(pi, i)]); - } - inner = expr.slice(1, -1); - if (inner.length) { - nested = new Lexer().tokenize(inner, { - line: this.line, - rewrite: false - }); - nested.pop(); - if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') { - nested.shift(); - } - if (len = nested.length) { - if (len > 1) { - nested.unshift(['(', '(', this.line]); - nested.push([')', ')', this.line]); - } - tokens.push(['TOKENS', nested]); - } - } - i += expr.length; - pi = i + 1; - } - if ((i > pi && pi < str.length)) { - tokens.push(['NEOSTRING', str.slice(pi)]); - } - if (regex) { - return tokens; - } - if (!tokens.length) { - return this.token('STRING', '""'); - } - if (tokens[0][0] !== 'NEOSTRING') { - tokens.unshift(['', '']); - } - if (interpolated = tokens.length > 1) { - this.token('(', '('); - } - for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) { - _ref3 = tokens[i], tag = _ref3[0], value = _ref3[1]; - if (i) { - this.token('+', '+'); - } - if (tag === 'TOKENS') { - (_ref4 = this.tokens).push.apply(_ref4, value); - } else { - this.token('STRING', this.makeString(value, '"', heredoc)); - } - } - if (interpolated) { - this.token(')', ')'); - } - return tokens; - }; - - Lexer.prototype.pair = function(tag) { - var size, wanted; - if (tag !== (wanted = last(this.ends))) { - if ('OUTDENT' !== wanted) { - this.error("unmatched " + tag); - } - this.indent -= size = last(this.indents); - this.outdentToken(size, true); - return this.pair(tag); - } - return this.ends.pop(); - }; - - Lexer.prototype.token = function(tag, value) { - return this.tokens.push([tag, value, this.line]); - }; - - Lexer.prototype.tag = function(index, tag) { - var tok; - return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]); - }; - - Lexer.prototype.value = function(index, val) { - var tok; - return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]); - }; - - Lexer.prototype.unfinished = function() { - var _ref2; - return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS'); - }; - - Lexer.prototype.escapeLines = function(str, heredoc) { - return str.replace(MULTILINER, heredoc ? '\\n' : ''); - }; - - Lexer.prototype.makeString = function(body, quote, heredoc) { - if (!body) { - return quote + quote; - } - body = body.replace(/\\([\s\S])/g, function(match, contents) { - if (contents === '\n' || contents === quote) { - return contents; - } else { - return match; - } - }); - body = body.replace(RegExp("" + quote, "g"), '\\$&'); - return quote + this.escapeLines(body, heredoc) + quote; - }; - - Lexer.prototype.error = function(message) { - throw SyntaxError("" + message + " on line " + (this.line + 1)); - }; - - return Lexer; - - })(); - - JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super']; - - COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']; - - COFFEE_ALIAS_MAP = { - and: '&&', - or: '||', - is: '==', - isnt: '!=', - not: '!', - yes: 'true', - no: 'false', - on: 'true', - off: 'false' - }; - - COFFEE_ALIASES = (function() { - var _results; - _results = []; - for (key in COFFEE_ALIAS_MAP) { - _results.push(key); - } - return _results; - })(); - - COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES); - - RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield']; - - STRICT_PROSCRIBED = ['arguments', 'eval']; - - JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED); - - exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED); - - exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED; - - IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/; - - NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; - - HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/; - - OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/; - - WHITESPACE = /^[^\n\S]+/; - - COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/; - - CODE = /^[-=]>/; - - MULTI_DENT = /^(?:\n[^\n\S]*)+/; - - SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/; - - JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/; - - REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/; - - HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/; - - HEREGEX_OMIT = /\s+(?:#.*)?/g; - - MULTILINER = /\n/g; - - HEREDOC_INDENT = /\n+([^\n\S]*)/g; - - HEREDOC_ILLEGAL = /\*\//; - - LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/; - - TRAILING_SPACES = /\s+$/; - - COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']; - - UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']; - - LOGIC = ['&&', '||', '&', '|', '^']; - - SHIFT = ['<<', '>>', '>>>']; - - COMPARE = ['==', '!=', '<', '>', '<=', '>=']; - - MATH = ['*', '/', '%']; - - RELATION = ['IN', 'OF', 'INSTANCEOF']; - - BOOL = ['TRUE', 'FALSE']; - - NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']']; - - NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING'); - - CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']; - - INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED'); - - LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js deleted file mode 100644 index 799b68eb..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/nodes.js +++ /dev/null @@ -1,2986 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref, _ref1, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Scope = require('./scope').Scope; - - _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED; - - _ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last; - - exports.extend = extend; - - YES = function() { - return true; - }; - - NO = function() { - return false; - }; - - THIS = function() { - return this; - }; - - NEGATE = function() { - this.negated = !this.negated; - return this; - }; - - exports.Base = Base = (function() { - - function Base() {} - - Base.prototype.compile = function(o, lvl) { - var node; - o = extend({}, o); - if (lvl) { - o.level = lvl; - } - node = this.unfoldSoak(o) || this; - node.tab = o.indent; - if (o.level === LEVEL_TOP || !node.isStatement(o)) { - return node.compileNode(o); - } else { - return node.compileClosure(o); - } - }; - - Base.prototype.compileClosure = function(o) { - if (this.jumps()) { - throw SyntaxError('cannot use a pure statement in an expression.'); - } - o.sharedScope = true; - return Closure.wrap(this).compileNode(o); - }; - - Base.prototype.cache = function(o, level, reused) { - var ref, sub; - if (!this.isComplex()) { - ref = level ? this.compile(o, level) : this; - return [ref, ref]; - } else { - ref = new Literal(reused || o.scope.freeVariable('ref')); - sub = new Assign(ref, this); - if (level) { - return [sub.compile(o, level), ref.value]; - } else { - return [sub, ref]; - } - } - }; - - Base.prototype.compileLoopReference = function(o, name) { - var src, tmp; - src = tmp = this.compile(o, LEVEL_LIST); - if (!((-Infinity < +src && +src < Infinity) || IDENTIFIER.test(src) && o.scope.check(src, true))) { - src = "" + (tmp = o.scope.freeVariable(name)) + " = " + src; - } - return [src, tmp]; - }; - - Base.prototype.makeReturn = function(res) { - var me; - me = this.unwrapAll(); - if (res) { - return new Call(new Literal("" + res + ".push"), [me]); - } else { - return new Return(me); - } - }; - - Base.prototype.contains = function(pred) { - var contains; - contains = false; - this.traverseChildren(false, function(node) { - if (pred(node)) { - contains = true; - return false; - } - }); - return contains; - }; - - Base.prototype.containsType = function(type) { - return this instanceof type || this.contains(function(node) { - return node instanceof type; - }); - }; - - Base.prototype.lastNonComment = function(list) { - var i; - i = list.length; - while (i--) { - if (!(list[i] instanceof Comment)) { - return list[i]; - } - } - return null; - }; - - Base.prototype.toString = function(idt, name) { - var tree; - if (idt == null) { - idt = ''; - } - if (name == null) { - name = this.constructor.name; - } - tree = '\n' + idt + name; - if (this.soak) { - tree += '?'; - } - this.eachChild(function(node) { - return tree += node.toString(idt + TAB); - }); - return tree; - }; - - Base.prototype.eachChild = function(func) { - var attr, child, _i, _j, _len, _len1, _ref2, _ref3; - if (!this.children) { - return this; - } - _ref2 = this.children; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - attr = _ref2[_i]; - if (this[attr]) { - _ref3 = flatten([this[attr]]); - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - child = _ref3[_j]; - if (func(child) === false) { - return this; - } - } - } - } - return this; - }; - - Base.prototype.traverseChildren = function(crossScope, func) { - return this.eachChild(function(child) { - if (func(child) === false) { - return false; - } - return child.traverseChildren(crossScope, func); - }); - }; - - Base.prototype.invert = function() { - return new Op('!', this); - }; - - Base.prototype.unwrapAll = function() { - var node; - node = this; - while (node !== (node = node.unwrap())) { - continue; - } - return node; - }; - - Base.prototype.children = []; - - Base.prototype.isStatement = NO; - - Base.prototype.jumps = NO; - - Base.prototype.isComplex = YES; - - Base.prototype.isChainable = NO; - - Base.prototype.isAssignable = NO; - - Base.prototype.unwrap = THIS; - - Base.prototype.unfoldSoak = NO; - - Base.prototype.assigns = NO; - - return Base; - - })(); - - exports.Block = Block = (function(_super) { - - __extends(Block, _super); - - function Block(nodes) { - this.expressions = compact(flatten(nodes || [])); - } - - Block.prototype.children = ['expressions']; - - Block.prototype.push = function(node) { - this.expressions.push(node); - return this; - }; - - Block.prototype.pop = function() { - return this.expressions.pop(); - }; - - Block.prototype.unshift = function(node) { - this.expressions.unshift(node); - return this; - }; - - Block.prototype.unwrap = function() { - if (this.expressions.length === 1) { - return this.expressions[0]; - } else { - return this; - } - }; - - Block.prototype.isEmpty = function() { - return !this.expressions.length; - }; - - Block.prototype.isStatement = function(o) { - var exp, _i, _len, _ref2; - _ref2 = this.expressions; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - exp = _ref2[_i]; - if (exp.isStatement(o)) { - return true; - } - } - return false; - }; - - Block.prototype.jumps = function(o) { - var exp, _i, _len, _ref2; - _ref2 = this.expressions; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - exp = _ref2[_i]; - if (exp.jumps(o)) { - return exp; - } - } - }; - - Block.prototype.makeReturn = function(res) { - var expr, len; - len = this.expressions.length; - while (len--) { - expr = this.expressions[len]; - if (!(expr instanceof Comment)) { - this.expressions[len] = expr.makeReturn(res); - if (expr instanceof Return && !expr.expression) { - this.expressions.splice(len, 1); - } - break; - } - } - return this; - }; - - Block.prototype.compile = function(o, level) { - if (o == null) { - o = {}; - } - if (o.scope) { - return Block.__super__.compile.call(this, o, level); - } else { - return this.compileRoot(o); - } - }; - - Block.prototype.compileNode = function(o) { - var code, codes, node, top, _i, _len, _ref2; - this.tab = o.indent; - top = o.level === LEVEL_TOP; - codes = []; - _ref2 = this.expressions; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - node = _ref2[_i]; - node = node.unwrapAll(); - node = node.unfoldSoak(o) || node; - if (node instanceof Block) { - codes.push(node.compileNode(o)); - } else if (top) { - node.front = true; - code = node.compile(o); - if (!node.isStatement(o)) { - code = "" + this.tab + code + ";"; - if (node instanceof Literal) { - code = "" + code + "\n"; - } - } - codes.push(code); - } else { - codes.push(node.compile(o, LEVEL_LIST)); - } - } - if (top) { - if (this.spaced) { - return "\n" + (codes.join('\n\n')) + "\n"; - } else { - return codes.join('\n'); - } - } - code = codes.join(', ') || 'void 0'; - if (codes.length > 1 && o.level >= LEVEL_LIST) { - return "(" + code + ")"; - } else { - return code; - } - }; - - Block.prototype.compileRoot = function(o) { - var code, exp, i, prelude, preludeExps, rest; - o.indent = o.bare ? '' : TAB; - o.scope = new Scope(null, this, null); - o.level = LEVEL_TOP; - this.spaced = true; - prelude = ""; - if (!o.bare) { - preludeExps = (function() { - var _i, _len, _ref2, _results; - _ref2 = this.expressions; - _results = []; - for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { - exp = _ref2[i]; - if (!(exp.unwrap() instanceof Comment)) { - break; - } - _results.push(exp); - } - return _results; - }).call(this); - rest = this.expressions.slice(preludeExps.length); - this.expressions = preludeExps; - if (preludeExps.length) { - prelude = "" + (this.compileNode(merge(o, { - indent: '' - }))) + "\n"; - } - this.expressions = rest; - } - code = this.compileWithDeclarations(o); - if (o.bare) { - return code; - } - return "" + prelude + "(function() {\n" + code + "\n}).call(this);\n"; - }; - - Block.prototype.compileWithDeclarations = function(o) { - var assigns, code, declars, exp, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4; - code = post = ''; - _ref2 = this.expressions; - for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { - exp = _ref2[i]; - exp = exp.unwrap(); - if (!(exp instanceof Comment || exp instanceof Literal)) { - break; - } - } - o = merge(o, { - level: LEVEL_TOP - }); - if (i) { - rest = this.expressions.splice(i, 9e9); - _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1]; - _ref4 = [this.compileNode(o), spaced], code = _ref4[0], this.spaced = _ref4[1]; - this.expressions = rest; - } - post = this.compileNode(o); - scope = o.scope; - if (scope.expressions === this) { - declars = o.scope.hasDeclarations(); - assigns = scope.hasAssignments; - if (declars || assigns) { - if (i) { - code += '\n'; - } - code += "" + this.tab + "var "; - if (declars) { - code += scope.declaredVariables().join(', '); - } - if (assigns) { - if (declars) { - code += ",\n" + (this.tab + TAB); - } - code += scope.assignedVariables().join(",\n" + (this.tab + TAB)); - } - code += ';\n'; - } - } - return code + post; - }; - - Block.wrap = function(nodes) { - if (nodes.length === 1 && nodes[0] instanceof Block) { - return nodes[0]; - } - return new Block(nodes); - }; - - return Block; - - })(Base); - - exports.Literal = Literal = (function(_super) { - - __extends(Literal, _super); - - function Literal(value) { - this.value = value; - } - - Literal.prototype.makeReturn = function() { - if (this.isStatement()) { - return this; - } else { - return Literal.__super__.makeReturn.apply(this, arguments); - } - }; - - Literal.prototype.isAssignable = function() { - return IDENTIFIER.test(this.value); - }; - - Literal.prototype.isStatement = function() { - var _ref2; - return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger'; - }; - - Literal.prototype.isComplex = NO; - - Literal.prototype.assigns = function(name) { - return name === this.value; - }; - - Literal.prototype.jumps = function(o) { - if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) { - return this; - } - if (this.value === 'continue' && !(o != null ? o.loop : void 0)) { - return this; - } - }; - - Literal.prototype.compileNode = function(o) { - var code, _ref2; - code = this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value; - if (this.isStatement()) { - return "" + this.tab + code + ";"; - } else { - return code; - } - }; - - Literal.prototype.toString = function() { - return ' "' + this.value + '"'; - }; - - return Literal; - - })(Base); - - exports.Undefined = (function(_super) { - - __extends(Undefined, _super); - - function Undefined() { - return Undefined.__super__.constructor.apply(this, arguments); - } - - Undefined.prototype.isAssignable = NO; - - Undefined.prototype.isComplex = NO; - - Undefined.prototype.compileNode = function(o) { - if (o.level >= LEVEL_ACCESS) { - return '(void 0)'; - } else { - return 'void 0'; - } - }; - - return Undefined; - - })(Base); - - exports.Null = (function(_super) { - - __extends(Null, _super); - - function Null() { - return Null.__super__.constructor.apply(this, arguments); - } - - Null.prototype.isAssignable = NO; - - Null.prototype.isComplex = NO; - - Null.prototype.compileNode = function() { - return "null"; - }; - - return Null; - - })(Base); - - exports.Bool = (function(_super) { - - __extends(Bool, _super); - - Bool.prototype.isAssignable = NO; - - Bool.prototype.isComplex = NO; - - Bool.prototype.compileNode = function() { - return this.val; - }; - - function Bool(val) { - this.val = val; - } - - return Bool; - - })(Base); - - exports.Return = Return = (function(_super) { - - __extends(Return, _super); - - function Return(expr) { - if (expr && !expr.unwrap().isUndefined) { - this.expression = expr; - } - } - - Return.prototype.children = ['expression']; - - Return.prototype.isStatement = YES; - - Return.prototype.makeReturn = THIS; - - Return.prototype.jumps = THIS; - - Return.prototype.compile = function(o, level) { - var expr, _ref2; - expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0; - if (expr && !(expr instanceof Return)) { - return expr.compile(o, level); - } else { - return Return.__super__.compile.call(this, o, level); - } - }; - - Return.prototype.compileNode = function(o) { - return this.tab + ("return" + [this.expression ? " " + (this.expression.compile(o, LEVEL_PAREN)) : void 0] + ";"); - }; - - return Return; - - })(Base); - - exports.Value = Value = (function(_super) { - - __extends(Value, _super); - - function Value(base, props, tag) { - if (!props && base instanceof Value) { - return base; - } - this.base = base; - this.properties = props || []; - if (tag) { - this[tag] = true; - } - return this; - } - - Value.prototype.children = ['base', 'properties']; - - Value.prototype.add = function(props) { - this.properties = this.properties.concat(props); - return this; - }; - - Value.prototype.hasProperties = function() { - return !!this.properties.length; - }; - - Value.prototype.isArray = function() { - return !this.properties.length && this.base instanceof Arr; - }; - - Value.prototype.isComplex = function() { - return this.hasProperties() || this.base.isComplex(); - }; - - Value.prototype.isAssignable = function() { - return this.hasProperties() || this.base.isAssignable(); - }; - - Value.prototype.isSimpleNumber = function() { - return this.base instanceof Literal && SIMPLENUM.test(this.base.value); - }; - - Value.prototype.isString = function() { - return this.base instanceof Literal && IS_STRING.test(this.base.value); - }; - - Value.prototype.isAtomic = function() { - var node, _i, _len, _ref2; - _ref2 = this.properties.concat(this.base); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - node = _ref2[_i]; - if (node.soak || node instanceof Call) { - return false; - } - } - return true; - }; - - Value.prototype.isStatement = function(o) { - return !this.properties.length && this.base.isStatement(o); - }; - - Value.prototype.assigns = function(name) { - return !this.properties.length && this.base.assigns(name); - }; - - Value.prototype.jumps = function(o) { - return !this.properties.length && this.base.jumps(o); - }; - - Value.prototype.isObject = function(onlyGenerated) { - if (this.properties.length) { - return false; - } - return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated); - }; - - Value.prototype.isSplice = function() { - return last(this.properties) instanceof Slice; - }; - - Value.prototype.unwrap = function() { - if (this.properties.length) { - return this; - } else { - return this.base; - } - }; - - Value.prototype.cacheReference = function(o) { - var base, bref, name, nref; - name = last(this.properties); - if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) { - return [this, this]; - } - base = new Value(this.base, this.properties.slice(0, -1)); - if (base.isComplex()) { - bref = new Literal(o.scope.freeVariable('base')); - base = new Value(new Parens(new Assign(bref, base))); - } - if (!name) { - return [base, bref]; - } - if (name.isComplex()) { - nref = new Literal(o.scope.freeVariable('name')); - name = new Index(new Assign(nref, name.index)); - nref = new Index(nref); - } - return [base.add(name), new Value(bref || base.base, [nref || name])]; - }; - - Value.prototype.compileNode = function(o) { - var code, prop, props, _i, _len; - this.base.front = this.front; - props = this.properties; - code = this.base.compile(o, props.length ? LEVEL_ACCESS : null); - if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(code)) { - code = "" + code + "."; - } - for (_i = 0, _len = props.length; _i < _len; _i++) { - prop = props[_i]; - code += prop.compile(o); - } - return code; - }; - - Value.prototype.unfoldSoak = function(o) { - var result, - _this = this; - if (this.unfoldedSoak != null) { - return this.unfoldedSoak; - } - result = (function() { - var fst, i, ifn, prop, ref, snd, _i, _len, _ref2; - if (ifn = _this.base.unfoldSoak(o)) { - Array.prototype.push.apply(ifn.body.properties, _this.properties); - return ifn; - } - _ref2 = _this.properties; - for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { - prop = _ref2[i]; - if (!prop.soak) { - continue; - } - prop.soak = false; - fst = new Value(_this.base, _this.properties.slice(0, i)); - snd = new Value(_this.base, _this.properties.slice(i)); - if (fst.isComplex()) { - ref = new Literal(o.scope.freeVariable('ref')); - fst = new Parens(new Assign(ref, fst)); - snd.base = ref; - } - return new If(new Existence(fst), snd, { - soak: true - }); - } - return null; - })(); - return this.unfoldedSoak = result || false; - }; - - return Value; - - })(Base); - - exports.Comment = Comment = (function(_super) { - - __extends(Comment, _super); - - function Comment(comment) { - this.comment = comment; - } - - Comment.prototype.isStatement = YES; - - Comment.prototype.makeReturn = THIS; - - Comment.prototype.compileNode = function(o, level) { - var code; - code = '/*' + multident(this.comment, this.tab) + ("\n" + this.tab + "*/\n"); - if ((level || o.level) === LEVEL_TOP) { - code = o.indent + code; - } - return code; - }; - - return Comment; - - })(Base); - - exports.Call = Call = (function(_super) { - - __extends(Call, _super); - - function Call(variable, args, soak) { - this.args = args != null ? args : []; - this.soak = soak; - this.isNew = false; - this.isSuper = variable === 'super'; - this.variable = this.isSuper ? null : variable; - } - - Call.prototype.children = ['variable', 'args']; - - Call.prototype.newInstance = function() { - var base, _ref2; - base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable; - if (base instanceof Call && !base.isNew) { - base.newInstance(); - } else { - this.isNew = true; - } - return this; - }; - - Call.prototype.superReference = function(o) { - var accesses, method, name; - method = o.scope.namedMethod(); - if (!method) { - throw SyntaxError('cannot call super outside of a function.'); - } - name = method.name; - if (name == null) { - throw SyntaxError('cannot call super on an anonymous function.'); - } - if (method.klass) { - accesses = [new Access(new Literal('__super__'))]; - if (method["static"]) { - accesses.push(new Access(new Literal('constructor'))); - } - accesses.push(new Access(new Literal(name))); - return (new Value(new Literal(method.klass), accesses)).compile(o); - } else { - return "" + name + ".__super__.constructor"; - } - }; - - Call.prototype.superThis = function(o) { - var method; - method = o.scope.method; - return (method && !method.klass && method.context) || "this"; - }; - - Call.prototype.unfoldSoak = function(o) { - var call, ifn, left, list, rite, _i, _len, _ref2, _ref3; - if (this.soak) { - if (this.variable) { - if (ifn = unfoldSoak(o, this, 'variable')) { - return ifn; - } - _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1]; - } else { - left = new Literal(this.superReference(o)); - rite = new Value(left); - } - rite = new Call(rite, this.args); - rite.isNew = this.isNew; - left = new Literal("typeof " + (left.compile(o)) + " === \"function\""); - return new If(left, new Value(rite), { - soak: true - }); - } - call = this; - list = []; - while (true) { - if (call.variable instanceof Call) { - list.push(call); - call = call.variable; - continue; - } - if (!(call.variable instanceof Value)) { - break; - } - list.push(call); - if (!((call = call.variable.base) instanceof Call)) { - break; - } - } - _ref3 = list.reverse(); - for (_i = 0, _len = _ref3.length; _i < _len; _i++) { - call = _ref3[_i]; - if (ifn) { - if (call.variable instanceof Call) { - call.variable = ifn; - } else { - call.variable.base = ifn; - } - } - ifn = unfoldSoak(o, call, 'variable'); - } - return ifn; - }; - - Call.prototype.filterImplicitObjects = function(list) { - var node, nodes, obj, prop, properties, _i, _j, _len, _len1, _ref2; - nodes = []; - for (_i = 0, _len = list.length; _i < _len; _i++) { - node = list[_i]; - if (!((typeof node.isObject === "function" ? node.isObject() : void 0) && node.base.generated)) { - nodes.push(node); - continue; - } - obj = null; - _ref2 = node.base.properties; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - prop = _ref2[_j]; - if (prop instanceof Assign || prop instanceof Comment) { - if (!obj) { - nodes.push(obj = new Obj(properties = [], true)); - } - properties.push(prop); - } else { - nodes.push(prop); - obj = null; - } - } - } - return nodes; - }; - - Call.prototype.compileNode = function(o) { - var arg, args, code, _ref2; - if ((_ref2 = this.variable) != null) { - _ref2.front = this.front; - } - if (code = Splat.compileSplattedArray(o, this.args, true)) { - return this.compileSplat(o, code); - } - args = this.filterImplicitObjects(this.args); - args = ((function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = args.length; _i < _len; _i++) { - arg = args[_i]; - _results.push(arg.compile(o, LEVEL_LIST)); - } - return _results; - })()).join(', '); - if (this.isSuper) { - return this.superReference(o) + (".call(" + (this.superThis(o)) + (args && ', ' + args) + ")"); - } else { - return (this.isNew ? 'new ' : '') + this.variable.compile(o, LEVEL_ACCESS) + ("(" + args + ")"); - } - }; - - Call.prototype.compileSuper = function(args, o) { - return "" + (this.superReference(o)) + ".call(" + (this.superThis(o)) + (args.length ? ', ' : '') + args + ")"; - }; - - Call.prototype.compileSplat = function(o, splatArgs) { - var base, fun, idt, name, ref; - if (this.isSuper) { - return "" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", " + splatArgs + ")"; - } - if (this.isNew) { - idt = this.tab + TAB; - return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args), t = typeof result;\n" + idt + "return t == \"object\" || t == \"function\" ? result || child : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})"; - } - base = new Value(this.variable); - if ((name = base.properties.pop()) && base.isComplex()) { - ref = o.scope.freeVariable('ref'); - fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o)); - } else { - fun = base.compile(o, LEVEL_ACCESS); - if (SIMPLENUM.test(fun)) { - fun = "(" + fun + ")"; - } - if (name) { - ref = fun; - fun += name.compile(o); - } else { - ref = 'null'; - } - } - return "" + fun + ".apply(" + ref + ", " + splatArgs + ")"; - }; - - return Call; - - })(Base); - - exports.Extends = Extends = (function(_super) { - - __extends(Extends, _super); - - function Extends(child, parent) { - this.child = child; - this.parent = parent; - } - - Extends.prototype.children = ['child', 'parent']; - - Extends.prototype.compile = function(o) { - return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o); - }; - - return Extends; - - })(Base); - - exports.Access = Access = (function(_super) { - - __extends(Access, _super); - - function Access(name, tag) { - this.name = name; - this.name.asKey = true; - this.soak = tag === 'soak'; - } - - Access.prototype.children = ['name']; - - Access.prototype.compile = function(o) { - var name; - name = this.name.compile(o); - if (IDENTIFIER.test(name)) { - return "." + name; - } else { - return "[" + name + "]"; - } - }; - - Access.prototype.isComplex = NO; - - return Access; - - })(Base); - - exports.Index = Index = (function(_super) { - - __extends(Index, _super); - - function Index(index) { - this.index = index; - } - - Index.prototype.children = ['index']; - - Index.prototype.compile = function(o) { - return "[" + (this.index.compile(o, LEVEL_PAREN)) + "]"; - }; - - Index.prototype.isComplex = function() { - return this.index.isComplex(); - }; - - return Index; - - })(Base); - - exports.Range = Range = (function(_super) { - - __extends(Range, _super); - - Range.prototype.children = ['from', 'to']; - - function Range(from, to, tag) { - this.from = from; - this.to = to; - this.exclusive = tag === 'exclusive'; - this.equals = this.exclusive ? '' : '='; - } - - Range.prototype.compileVariables = function(o) { - var step, _ref2, _ref3, _ref4, _ref5; - o = merge(o, { - top: true - }); - _ref2 = this.from.cache(o, LEVEL_LIST), this.fromC = _ref2[0], this.fromVar = _ref2[1]; - _ref3 = this.to.cache(o, LEVEL_LIST), this.toC = _ref3[0], this.toVar = _ref3[1]; - if (step = del(o, 'step')) { - _ref4 = step.cache(o, LEVEL_LIST), this.step = _ref4[0], this.stepVar = _ref4[1]; - } - _ref5 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)], this.fromNum = _ref5[0], this.toNum = _ref5[1]; - if (this.stepVar) { - return this.stepNum = this.stepVar.match(SIMPLENUM); - } - }; - - Range.prototype.compileNode = function(o) { - var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3; - if (!this.fromVar) { - this.compileVariables(o); - } - if (!o.index) { - return this.compileArray(o); - } - known = this.fromNum && this.toNum; - idx = del(o, 'index'); - idxName = del(o, 'name'); - namedIndex = idxName && idxName !== idx; - varPart = "" + idx + " = " + this.fromC; - if (this.toC !== this.toVar) { - varPart += ", " + this.toC; - } - if (this.step !== this.stepVar) { - varPart += ", " + this.step; - } - _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1]; - condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar); - stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--"; - if (namedIndex) { - varPart = "" + idxName + " = " + varPart; - } - if (namedIndex) { - stepPart = "" + idxName + " = " + stepPart; - } - return "" + varPart + "; " + condPart + "; " + stepPart; - }; - - Range.prototype.compileArray = function(o) { - var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results; - if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) { - range = (function() { - _results = []; - for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); } - return _results; - }).apply(this); - if (this.exclusive) { - range.pop(); - } - return "[" + (range.join(', ')) + "]"; - } - idt = this.tab + TAB; - i = o.scope.freeVariable('i'); - result = o.scope.freeVariable('results'); - pre = "\n" + idt + result + " = [];"; - if (this.fromNum && this.toNum) { - o.index = i; - body = this.compileNode(o); - } else { - vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : ''); - cond = "" + this.fromVar + " <= " + this.toVar; - body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--"; - } - post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent; - hasArgs = function(node) { - return node != null ? node.contains(function(n) { - return n instanceof Literal && n.value === 'arguments' && !n.asKey; - }) : void 0; - }; - if (hasArgs(this.from) || hasArgs(this.to)) { - args = ', arguments'; - } - return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")"; - }; - - return Range; - - })(Base); - - exports.Slice = Slice = (function(_super) { - - __extends(Slice, _super); - - Slice.prototype.children = ['range']; - - function Slice(range) { - this.range = range; - Slice.__super__.constructor.call(this); - } - - Slice.prototype.compileNode = function(o) { - var compiled, from, fromStr, to, toStr, _ref2; - _ref2 = this.range, to = _ref2.to, from = _ref2.from; - fromStr = from && from.compile(o, LEVEL_PAREN) || '0'; - compiled = to && to.compile(o, LEVEL_PAREN); - if (to && !(!this.range.exclusive && +compiled === -1)) { - toStr = ', ' + (this.range.exclusive ? compiled : SIMPLENUM.test(compiled) ? "" + (+compiled + 1) : (compiled = to.compile(o, LEVEL_ACCESS), "" + compiled + " + 1 || 9e9")); - } - return ".slice(" + fromStr + (toStr || '') + ")"; - }; - - return Slice; - - })(Base); - - exports.Obj = Obj = (function(_super) { - - __extends(Obj, _super); - - function Obj(props, generated) { - this.generated = generated != null ? generated : false; - this.objects = this.properties = props || []; - } - - Obj.prototype.children = ['properties']; - - Obj.prototype.compileNode = function(o) { - var i, idt, indent, join, lastNoncom, node, obj, prop, propName, propNames, props, _i, _j, _len, _len1, _ref2; - props = this.properties; - propNames = []; - _ref2 = this.properties; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - prop = _ref2[_i]; - if (prop.isComplex()) { - prop = prop.variable; - } - if (prop != null) { - propName = prop.unwrapAll().value.toString(); - if (__indexOf.call(propNames, propName) >= 0) { - throw SyntaxError("multiple object literal properties named \"" + propName + "\""); - } - propNames.push(propName); - } - } - if (!props.length) { - return (this.front ? '({})' : '{}'); - } - if (this.generated) { - for (_j = 0, _len1 = props.length; _j < _len1; _j++) { - node = props[_j]; - if (node instanceof Value) { - throw new Error('cannot have an implicit value in an implicit object'); - } - } - } - idt = o.indent += TAB; - lastNoncom = this.lastNonComment(this.properties); - props = (function() { - var _k, _len2, _results; - _results = []; - for (i = _k = 0, _len2 = props.length; _k < _len2; i = ++_k) { - prop = props[i]; - join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; - indent = prop instanceof Comment ? '' : idt; - if (prop instanceof Value && prop["this"]) { - prop = new Assign(prop.properties[0].name, prop, 'object'); - } - if (!(prop instanceof Comment)) { - if (!(prop instanceof Assign)) { - prop = new Assign(prop, prop, 'object'); - } - (prop.variable.base || prop.variable).asKey = true; - } - _results.push(indent + prop.compile(o, LEVEL_TOP) + join); - } - return _results; - })(); - props = props.join(''); - obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}"; - if (this.front) { - return "(" + obj + ")"; - } else { - return obj; - } - }; - - Obj.prototype.assigns = function(name) { - var prop, _i, _len, _ref2; - _ref2 = this.properties; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - prop = _ref2[_i]; - if (prop.assigns(name)) { - return true; - } - } - return false; - }; - - return Obj; - - })(Base); - - exports.Arr = Arr = (function(_super) { - - __extends(Arr, _super); - - function Arr(objs) { - this.objects = objs || []; - } - - Arr.prototype.children = ['objects']; - - Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects; - - Arr.prototype.compileNode = function(o) { - var code, obj, objs; - if (!this.objects.length) { - return '[]'; - } - o.indent += TAB; - objs = this.filterImplicitObjects(this.objects); - if (code = Splat.compileSplattedArray(o, objs)) { - return code; - } - code = ((function() { - var _i, _len, _results; - _results = []; - for (_i = 0, _len = objs.length; _i < _len; _i++) { - obj = objs[_i]; - _results.push(obj.compile(o, LEVEL_LIST)); - } - return _results; - })()).join(', '); - if (code.indexOf('\n') >= 0) { - return "[\n" + o.indent + code + "\n" + this.tab + "]"; - } else { - return "[" + code + "]"; - } - }; - - Arr.prototype.assigns = function(name) { - var obj, _i, _len, _ref2; - _ref2 = this.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; - if (obj.assigns(name)) { - return true; - } - } - return false; - }; - - return Arr; - - })(Base); - - exports.Class = Class = (function(_super) { - - __extends(Class, _super); - - function Class(variable, parent, body) { - this.variable = variable; - this.parent = parent; - this.body = body != null ? body : new Block; - this.boundFuncs = []; - this.body.classBody = true; - } - - Class.prototype.children = ['variable', 'parent', 'body']; - - Class.prototype.determineName = function() { - var decl, tail; - if (!this.variable) { - return null; - } - decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value; - if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) { - throw SyntaxError("variable name may not be " + decl); - } - return decl && (decl = IDENTIFIER.test(decl) && decl); - }; - - Class.prototype.setContext = function(name) { - return this.body.traverseChildren(false, function(node) { - if (node.classBody) { - return false; - } - if (node instanceof Literal && node.value === 'this') { - return node.value = name; - } else if (node instanceof Code) { - node.klass = name; - if (node.bound) { - return node.context = name; - } - } - }); - }; - - Class.prototype.addBoundFunctions = function(o) { - var bvar, lhs, _i, _len, _ref2, _results; - if (this.boundFuncs.length) { - _ref2 = this.boundFuncs; - _results = []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - bvar = _ref2[_i]; - lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o); - _results.push(this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"))); - } - return _results; - } - }; - - Class.prototype.addProperties = function(node, name, o) { - var assign, base, exprs, func, props; - props = node.base.properties.slice(0); - exprs = (function() { - var _results; - _results = []; - while (assign = props.shift()) { - if (assign instanceof Assign) { - base = assign.variable.base; - delete assign.context; - func = assign.value; - if (base.value === 'constructor') { - if (this.ctor) { - throw new Error('cannot define more than one constructor in a class'); - } - if (func.bound) { - throw new Error('cannot define a constructor as a bound function'); - } - if (func instanceof Code) { - assign = this.ctor = func; - } else { - this.externalCtor = o.scope.freeVariable('class'); - assign = new Assign(new Literal(this.externalCtor), func); - } - } else { - if (assign.variable["this"]) { - func["static"] = true; - if (func.bound) { - func.context = name; - } - } else { - assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]); - if (func instanceof Code && func.bound) { - this.boundFuncs.push(base); - func.bound = false; - } - } - } - } - _results.push(assign); - } - return _results; - }).call(this); - return compact(exprs); - }; - - Class.prototype.walkBody = function(name, o) { - var _this = this; - return this.traverseChildren(false, function(child) { - var exps, i, node, _i, _len, _ref2; - if (child instanceof Class) { - return false; - } - if (child instanceof Block) { - _ref2 = exps = child.expressions; - for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { - node = _ref2[i]; - if (node instanceof Value && node.isObject(true)) { - exps[i] = _this.addProperties(node, name, o); - } - } - return child.expressions = exps = flatten(exps); - } - }); - }; - - Class.prototype.hoistDirectivePrologue = function() { - var expressions, index, node; - index = 0; - expressions = this.body.expressions; - while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) { - ++index; - } - return this.directives = expressions.splice(0, index); - }; - - Class.prototype.ensureConstructor = function(name) { - if (!this.ctor) { - this.ctor = new Code; - if (this.parent) { - this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)")); - } - if (this.externalCtor) { - this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)")); - } - this.ctor.body.makeReturn(); - this.body.expressions.unshift(this.ctor); - } - this.ctor.ctor = this.ctor.name = name; - this.ctor.klass = null; - return this.ctor.noReturn = true; - }; - - Class.prototype.compileNode = function(o) { - var call, decl, klass, lname, name, params, _ref2; - decl = this.determineName(); - name = decl || '_Class'; - if (name.reserved) { - name = "_" + name; - } - lname = new Literal(name); - this.hoistDirectivePrologue(); - this.setContext(name); - this.walkBody(name, o); - this.ensureConstructor(name); - this.body.spaced = true; - if (!(this.ctor instanceof Code)) { - this.body.expressions.unshift(this.ctor); - } - this.body.expressions.push(lname); - (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives); - this.addBoundFunctions(o); - call = Closure.wrap(this.body); - if (this.parent) { - this.superClass = new Literal(o.scope.freeVariable('super', false)); - this.body.expressions.unshift(new Extends(lname, this.superClass)); - call.args.push(this.parent); - params = call.variable.params || call.variable.base.params; - params.push(new Param(this.superClass)); - } - klass = new Parens(call, true); - if (this.variable) { - klass = new Assign(this.variable, klass); - } - return klass.compile(o); - }; - - return Class; - - })(Base); - - exports.Assign = Assign = (function(_super) { - - __extends(Assign, _super); - - function Assign(variable, value, context, options) { - var forbidden, name, _ref2; - this.variable = variable; - this.value = value; - this.context = context; - this.param = options && options.param; - this.subpattern = options && options.subpattern; - forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0); - if (forbidden && this.context !== 'object') { - throw SyntaxError("variable name may not be \"" + name + "\""); - } - } - - Assign.prototype.children = ['variable', 'value']; - - Assign.prototype.isStatement = function(o) { - return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0; - }; - - Assign.prototype.assigns = function(name) { - return this[this.context === 'object' ? 'value' : 'variable'].assigns(name); - }; - - Assign.prototype.unfoldSoak = function(o) { - return unfoldSoak(o, this, 'variable'); - }; - - Assign.prototype.compileNode = function(o) { - var isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5; - if (isValue = this.variable instanceof Value) { - if (this.variable.isArray() || this.variable.isObject()) { - return this.compilePatternMatch(o); - } - if (this.variable.isSplice()) { - return this.compileSplice(o); - } - if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') { - return this.compileConditional(o); - } - } - name = this.variable.compile(o, LEVEL_LIST); - if (!this.context) { - if (!(varBase = this.variable.unwrapAll()).isAssignable()) { - throw SyntaxError("\"" + (this.variable.compile(o)) + "\" cannot be assigned."); - } - if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) { - if (this.param) { - o.scope.add(name, 'var'); - } else { - o.scope.find(name); - } - } - } - if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) { - if (match[1]) { - this.value.klass = match[1]; - } - this.value.name = (_ref3 = (_ref4 = (_ref5 = match[2]) != null ? _ref5 : match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5]; - } - val = this.value.compile(o, LEVEL_LIST); - if (this.context === 'object') { - return "" + name + ": " + val; - } - val = name + (" " + (this.context || '=') + " ") + val; - if (o.level <= LEVEL_LIST) { - return val; - } else { - return "(" + val + ")"; - } - }; - - Assign.prototype.compilePatternMatch = function(o) { - var acc, assigns, code, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; - top = o.level === LEVEL_TOP; - value = this.value; - objects = this.variable.base.objects; - if (!(olen = objects.length)) { - code = value.compile(o); - if (o.level >= LEVEL_OP) { - return "(" + code + ")"; - } else { - return code; - } - } - isObject = this.variable.isObject(); - if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) { - if (obj instanceof Assign) { - _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value; - } else { - if (obj.base instanceof Parens) { - _ref4 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1]; - } else { - idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0); - } - } - acc = IDENTIFIER.test(idx.unwrap().value || 0); - value = new Value(value); - value.properties.push(new (acc ? Access : Index)(idx)); - if (_ref5 = obj.unwrap().value, __indexOf.call(RESERVED, _ref5) >= 0) { - throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o))); - } - return new Assign(obj, value, null, { - param: this.param - }).compile(o, LEVEL_TOP); - } - vvar = value.compile(o, LEVEL_LIST); - assigns = []; - splat = false; - if (!IDENTIFIER.test(vvar) || this.variable.assigns(vvar)) { - assigns.push("" + (ref = o.scope.freeVariable('ref')) + " = " + vvar); - vvar = ref; - } - for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) { - obj = objects[i]; - idx = i; - if (isObject) { - if (obj instanceof Assign) { - _ref6 = obj, (_ref7 = _ref6.variable, idx = _ref7.base), obj = _ref6.value; - } else { - if (obj.base instanceof Parens) { - _ref8 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1]; - } else { - idx = obj["this"] ? obj.properties[0].name : obj; - } - } - } - if (!splat && obj instanceof Splat) { - name = obj.name.unwrap().value; - obj = obj.unwrap(); - val = "" + olen + " <= " + vvar + ".length ? " + (utility('slice')) + ".call(" + vvar + ", " + i; - if (rest = olen - i - 1) { - ivar = o.scope.freeVariable('i'); - val += ", " + ivar + " = " + vvar + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])"; - } else { - val += ") : []"; - } - val = new Literal(val); - splat = "" + ivar + "++"; - } else { - name = obj.unwrap().value; - if (obj instanceof Splat) { - obj = obj.name.compile(o); - throw new SyntaxError("multiple splats are disallowed in an assignment: " + obj + "..."); - } - if (typeof idx === 'number') { - idx = new Literal(splat || idx); - acc = false; - } else { - acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0); - } - val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]); - } - if ((name != null) && __indexOf.call(RESERVED, name) >= 0) { - throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o))); - } - assigns.push(new Assign(obj, val, null, { - param: this.param, - subpattern: true - }).compile(o, LEVEL_LIST)); - } - if (!(top || this.subpattern)) { - assigns.push(vvar); - } - code = assigns.join(', '); - if (o.level < LEVEL_LIST) { - return code; - } else { - return "(" + code + ")"; - } - }; - - Assign.prototype.compileConditional = function(o) { - var left, right, _ref2; - _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1]; - if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) { - throw new Error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been defined."); - } - if (__indexOf.call(this.context, "?") >= 0) { - o.isExistentialEquals = true; - } - return new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o); - }; - - Assign.prototype.compileSplice = function(o) { - var code, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4; - _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive; - name = this.variable.compile(o); - _ref3 = (from != null ? from.cache(o, LEVEL_OP) : void 0) || ['0', '0'], fromDecl = _ref3[0], fromRef = _ref3[1]; - if (to) { - if ((from != null ? from.isSimpleNumber() : void 0) && to.isSimpleNumber()) { - to = +to.compile(o) - +fromRef; - if (!exclusive) { - to += 1; - } - } else { - to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef; - if (!exclusive) { - to += ' + 1'; - } - } - } else { - to = "9e9"; - } - _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1]; - code = "[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat(" + valDef + ")), " + valRef; - if (o.level > LEVEL_TOP) { - return "(" + code + ")"; - } else { - return code; - } - }; - - return Assign; - - })(Base); - - exports.Code = Code = (function(_super) { - - __extends(Code, _super); - - function Code(params, body, tag) { - this.params = params || []; - this.body = body || new Block; - this.bound = tag === 'boundfunc'; - if (this.bound) { - this.context = '_this'; - } - } - - Code.prototype.children = ['params', 'body']; - - Code.prototype.isStatement = function() { - return !!this.ctor; - }; - - Code.prototype.jumps = NO; - - Code.prototype.compileNode = function(o) { - var code, exprs, i, idt, lit, name, p, param, params, ref, splats, uniqs, val, wasEmpty, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; - o.scope = new Scope(o.scope, this.body, this); - o.scope.shared = del(o, 'sharedScope'); - o.indent += TAB; - delete o.bare; - delete o.isExistentialEquals; - params = []; - exprs = []; - _ref2 = this.paramNames(); - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - name = _ref2[_i]; - if (!o.scope.check(name)) { - o.scope.parameter(name); - } - } - _ref3 = this.params; - for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { - param = _ref3[_j]; - if (!param.splat) { - continue; - } - _ref4 = this.params; - for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) { - p = _ref4[_k].name; - if (p["this"]) { - p = p.properties[0].name; - } - if (p.value) { - o.scope.add(p.value, 'var', true); - } - } - splats = new Assign(new Value(new Arr((function() { - var _l, _len3, _ref5, _results; - _ref5 = this.params; - _results = []; - for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) { - p = _ref5[_l]; - _results.push(p.asReference(o)); - } - return _results; - }).call(this))), new Value(new Literal('arguments'))); - break; - } - _ref5 = this.params; - for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) { - param = _ref5[_l]; - if (param.isComplex()) { - val = ref = param.asReference(o); - if (param.value) { - val = new Op('?', ref, param.value); - } - exprs.push(new Assign(new Value(param.name), val, '=', { - param: true - })); - } else { - ref = param; - if (param.value) { - lit = new Literal(ref.name.value + ' == null'); - val = new Assign(new Value(param.name), param.value, '='); - exprs.push(new If(lit, val)); - } - } - if (!splats) { - params.push(ref); - } - } - wasEmpty = this.body.isEmpty(); - if (splats) { - exprs.unshift(splats); - } - if (exprs.length) { - (_ref6 = this.body.expressions).unshift.apply(_ref6, exprs); - } - for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) { - p = params[i]; - o.scope.parameter(params[i] = p.compile(o)); - } - uniqs = []; - _ref7 = this.paramNames(); - for (_n = 0, _len5 = _ref7.length; _n < _len5; _n++) { - name = _ref7[_n]; - if (__indexOf.call(uniqs, name) >= 0) { - throw SyntaxError("multiple parameters named '" + name + "'"); - } - uniqs.push(name); - } - if (!(wasEmpty || this.noReturn)) { - this.body.makeReturn(); - } - if (this.bound) { - if ((_ref8 = o.scope.parent.method) != null ? _ref8.bound : void 0) { - this.bound = this.context = o.scope.parent.method.context; - } else if (!this["static"]) { - o.scope.parent.assign('_this', 'this'); - } - } - idt = o.indent; - code = 'function'; - if (this.ctor) { - code += ' ' + this.name; - } - code += '(' + params.join(', ') + ') {'; - if (!this.body.isEmpty()) { - code += "\n" + (this.body.compileWithDeclarations(o)) + "\n" + this.tab; - } - code += '}'; - if (this.ctor) { - return this.tab + code; - } - if (this.front || (o.level >= LEVEL_ACCESS)) { - return "(" + code + ")"; - } else { - return code; - } - }; - - Code.prototype.paramNames = function() { - var names, param, _i, _len, _ref2; - names = []; - _ref2 = this.params; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - param = _ref2[_i]; - names.push.apply(names, param.names()); - } - return names; - }; - - Code.prototype.traverseChildren = function(crossScope, func) { - if (crossScope) { - return Code.__super__.traverseChildren.call(this, crossScope, func); - } - }; - - return Code; - - })(Base); - - exports.Param = Param = (function(_super) { - - __extends(Param, _super); - - function Param(name, value, splat) { - var _ref2; - this.name = name; - this.value = value; - this.splat = splat; - if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { - throw SyntaxError("parameter name \"" + name + "\" is not allowed"); - } - } - - Param.prototype.children = ['name', 'value']; - - Param.prototype.compile = function(o) { - return this.name.compile(o, LEVEL_LIST); - }; - - Param.prototype.asReference = function(o) { - var node; - if (this.reference) { - return this.reference; - } - node = this.name; - if (node["this"]) { - node = node.properties[0].name; - if (node.value.reserved) { - node = new Literal(o.scope.freeVariable(node.value)); - } - } else if (node.isComplex()) { - node = new Literal(o.scope.freeVariable('arg')); - } - node = new Value(node); - if (this.splat) { - node = new Splat(node); - } - return this.reference = node; - }; - - Param.prototype.isComplex = function() { - return this.name.isComplex(); - }; - - Param.prototype.names = function(name) { - var atParam, names, obj, _i, _len, _ref2; - if (name == null) { - name = this.name; - } - atParam = function(obj) { - var value; - value = obj.properties[0].name.value; - if (value.reserved) { - return []; - } else { - return [value]; - } - }; - if (name instanceof Literal) { - return [name.value]; - } - if (name instanceof Value) { - return atParam(name); - } - names = []; - _ref2 = name.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; - if (obj instanceof Assign) { - names.push(obj.value.unwrap().value); - } else if (obj instanceof Splat) { - names.push(obj.name.unwrap().value); - } else if (obj instanceof Value) { - if (obj.isArray() || obj.isObject()) { - names.push.apply(names, this.names(obj.base)); - } else if (obj["this"]) { - names.push.apply(names, atParam(obj)); - } else { - names.push(obj.base.value); - } - } else { - throw SyntaxError("illegal parameter " + (obj.compile())); - } - } - return names; - }; - - return Param; - - })(Base); - - exports.Splat = Splat = (function(_super) { - - __extends(Splat, _super); - - Splat.prototype.children = ['name']; - - Splat.prototype.isAssignable = YES; - - function Splat(name) { - this.name = name.compile ? name : new Literal(name); - } - - Splat.prototype.assigns = function(name) { - return this.name.assigns(name); - }; - - Splat.prototype.compile = function(o) { - if (this.index != null) { - return this.compileParam(o); - } else { - return this.name.compile(o); - } - }; - - Splat.prototype.unwrap = function() { - return this.name; - }; - - Splat.compileSplattedArray = function(o, list, apply) { - var args, base, code, i, index, node, _i, _len; - index = -1; - while ((node = list[++index]) && !(node instanceof Splat)) { - continue; - } - if (index >= list.length) { - return ''; - } - if (list.length === 1) { - code = list[0].compile(o, LEVEL_LIST); - if (apply) { - return code; - } - return "" + (utility('slice')) + ".call(" + code + ")"; - } - args = list.slice(index); - for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { - node = args[i]; - code = node.compile(o, LEVEL_LIST); - args[i] = node instanceof Splat ? "" + (utility('slice')) + ".call(" + code + ")" : "[" + code + "]"; - } - if (index === 0) { - return args[0] + (".concat(" + (args.slice(1).join(', ')) + ")"); - } - base = (function() { - var _j, _len1, _ref2, _results; - _ref2 = list.slice(0, index); - _results = []; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - node = _ref2[_j]; - _results.push(node.compile(o, LEVEL_LIST)); - } - return _results; - })(); - return "[" + (base.join(', ')) + "].concat(" + (args.join(', ')) + ")"; - }; - - return Splat; - - })(Base); - - exports.While = While = (function(_super) { - - __extends(While, _super); - - function While(condition, options) { - this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition; - this.guard = options != null ? options.guard : void 0; - } - - While.prototype.children = ['condition', 'guard', 'body']; - - While.prototype.isStatement = YES; - - While.prototype.makeReturn = function(res) { - if (res) { - return While.__super__.makeReturn.apply(this, arguments); - } else { - this.returns = !this.jumps({ - loop: true - }); - return this; - } - }; - - While.prototype.addBody = function(body) { - this.body = body; - return this; - }; - - While.prototype.jumps = function() { - var expressions, node, _i, _len; - expressions = this.body.expressions; - if (!expressions.length) { - return false; - } - for (_i = 0, _len = expressions.length; _i < _len; _i++) { - node = expressions[_i]; - if (node.jumps({ - loop: true - })) { - return node; - } - } - return false; - }; - - While.prototype.compileNode = function(o) { - var body, code, rvar, set; - o.indent += TAB; - set = ''; - body = this.body; - if (body.isEmpty()) { - body = ''; - } else { - if (this.returns) { - body.makeReturn(rvar = o.scope.freeVariable('results')); - set = "" + this.tab + rvar + " = [];\n"; - } - if (this.guard) { - if (body.expressions.length > 1) { - body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); - } else { - if (this.guard) { - body = Block.wrap([new If(this.guard, body)]); - } - } - } - body = "\n" + (body.compile(o, LEVEL_TOP)) + "\n" + this.tab; - } - code = set + this.tab + ("while (" + (this.condition.compile(o, LEVEL_PAREN)) + ") {" + body + "}"); - if (this.returns) { - code += "\n" + this.tab + "return " + rvar + ";"; - } - return code; - }; - - return While; - - })(Base); - - exports.Op = Op = (function(_super) { - var CONVERSIONS, INVERSIONS; - - __extends(Op, _super); - - function Op(op, first, second, flip) { - if (op === 'in') { - return new In(first, second); - } - if (op === 'do') { - return this.generateDo(first); - } - if (op === 'new') { - if (first instanceof Call && !first["do"] && !first.isNew) { - return first.newInstance(); - } - if (first instanceof Code && first.bound || first["do"]) { - first = new Parens(first); - } - } - this.operator = CONVERSIONS[op] || op; - this.first = first; - this.second = second; - this.flip = !!flip; - return this; - } - - CONVERSIONS = { - '==': '===', - '!=': '!==', - 'of': 'in' - }; - - INVERSIONS = { - '!==': '===', - '===': '!==' - }; - - Op.prototype.children = ['first', 'second']; - - Op.prototype.isSimpleNumber = NO; - - Op.prototype.isUnary = function() { - return !this.second; - }; - - Op.prototype.isComplex = function() { - var _ref2; - return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex(); - }; - - Op.prototype.isChainable = function() { - var _ref2; - return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!=='; - }; - - Op.prototype.invert = function() { - var allInvertable, curr, fst, op, _ref2; - if (this.isChainable() && this.first.isChainable()) { - allInvertable = true; - curr = this; - while (curr && curr.operator) { - allInvertable && (allInvertable = curr.operator in INVERSIONS); - curr = curr.first; - } - if (!allInvertable) { - return new Parens(this).invert(); - } - curr = this; - while (curr && curr.operator) { - curr.invert = !curr.invert; - curr.operator = INVERSIONS[curr.operator]; - curr = curr.first; - } - return this; - } else if (op = INVERSIONS[this.operator]) { - this.operator = op; - if (this.first.unwrap() instanceof Op) { - this.first.invert(); - } - return this; - } else if (this.second) { - return new Parens(this).invert(); - } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) { - return fst; - } else { - return new Op('!', this); - } - }; - - Op.prototype.unfoldSoak = function(o) { - var _ref2; - return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first'); - }; - - Op.prototype.generateDo = function(exp) { - var call, func, param, passedParams, ref, _i, _len, _ref2; - passedParams = []; - func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp; - _ref2 = func.params || []; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - param = _ref2[_i]; - if (param.value) { - passedParams.push(param.value); - delete param.value; - } else { - passedParams.push(param); - } - } - call = new Call(exp, passedParams); - call["do"] = true; - return call; - }; - - Op.prototype.compileNode = function(o) { - var code, isChain, _ref2, _ref3; - isChain = this.isChainable() && this.first.isChainable(); - if (!isChain) { - this.first.front = this.front; - } - if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) { - throw SyntaxError('delete operand may not be argument or var'); - } - if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) { - throw SyntaxError('prefix increment/decrement may not have eval or arguments operand'); - } - if (this.isUnary()) { - return this.compileUnary(o); - } - if (isChain) { - return this.compileChain(o); - } - if (this.operator === '?') { - return this.compileExistence(o); - } - code = this.first.compile(o, LEVEL_OP) + ' ' + this.operator + ' ' + this.second.compile(o, LEVEL_OP); - if (o.level <= LEVEL_OP) { - return code; - } else { - return "(" + code + ")"; - } - }; - - Op.prototype.compileChain = function(o) { - var code, fst, shared, _ref2; - _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1]; - fst = this.first.compile(o, LEVEL_OP); - code = "" + fst + " " + (this.invert ? '&&' : '||') + " " + (shared.compile(o)) + " " + this.operator + " " + (this.second.compile(o, LEVEL_OP)); - return "(" + code + ")"; - }; - - Op.prototype.compileExistence = function(o) { - var fst, ref; - if (this.first.isComplex()) { - ref = new Literal(o.scope.freeVariable('ref')); - fst = new Parens(new Assign(ref, this.first)); - } else { - fst = this.first; - ref = fst; - } - return new If(new Existence(fst), ref, { - type: 'if' - }).addElse(this.second).compile(o); - }; - - Op.prototype.compileUnary = function(o) { - var op, parts, plusMinus; - if (o.level >= LEVEL_ACCESS) { - return (new Parens(this)).compile(o); - } - parts = [op = this.operator]; - plusMinus = op === '+' || op === '-'; - if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) { - parts.push(' '); - } - if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) { - this.first = new Parens(this.first); - } - parts.push(this.first.compile(o, LEVEL_OP)); - if (this.flip) { - parts.reverse(); - } - return parts.join(''); - }; - - Op.prototype.toString = function(idt) { - return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); - }; - - return Op; - - })(Base); - - exports.In = In = (function(_super) { - - __extends(In, _super); - - function In(object, array) { - this.object = object; - this.array = array; - } - - In.prototype.children = ['object', 'array']; - - In.prototype.invert = NEGATE; - - In.prototype.compileNode = function(o) { - var hasSplat, obj, _i, _len, _ref2; - if (this.array instanceof Value && this.array.isArray()) { - _ref2 = this.array.base.objects; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - obj = _ref2[_i]; - if (!(obj instanceof Splat)) { - continue; - } - hasSplat = true; - break; - } - if (!hasSplat) { - return this.compileOrTest(o); - } - } - return this.compileLoopTest(o); - }; - - In.prototype.compileOrTest = function(o) { - var cmp, cnj, i, item, ref, sub, tests, _ref2, _ref3; - if (this.array.base.objects.length === 0) { - return "" + (!!this.negated); - } - _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1]; - _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1]; - tests = (function() { - var _i, _len, _ref4, _results; - _ref4 = this.array.base.objects; - _results = []; - for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { - item = _ref4[i]; - _results.push((i ? ref : sub) + cmp + item.compile(o, LEVEL_ACCESS)); - } - return _results; - }).call(this); - tests = tests.join(cnj); - if (o.level < LEVEL_OP) { - return tests; - } else { - return "(" + tests + ")"; - } - }; - - In.prototype.compileLoopTest = function(o) { - var code, ref, sub, _ref2; - _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1]; - code = utility('indexOf') + (".call(" + (this.array.compile(o, LEVEL_LIST)) + ", " + ref + ") ") + (this.negated ? '< 0' : '>= 0'); - if (sub === ref) { - return code; - } - code = sub + ', ' + code; - if (o.level < LEVEL_LIST) { - return code; - } else { - return "(" + code + ")"; - } - }; - - In.prototype.toString = function(idt) { - return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : '')); - }; - - return In; - - })(Base); - - exports.Try = Try = (function(_super) { - - __extends(Try, _super); - - function Try(attempt, error, recovery, ensure) { - this.attempt = attempt; - this.error = error; - this.recovery = recovery; - this.ensure = ensure; - } - - Try.prototype.children = ['attempt', 'recovery', 'ensure']; - - Try.prototype.isStatement = YES; - - Try.prototype.jumps = function(o) { - var _ref2; - return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0); - }; - - Try.prototype.makeReturn = function(res) { - if (this.attempt) { - this.attempt = this.attempt.makeReturn(res); - } - if (this.recovery) { - this.recovery = this.recovery.makeReturn(res); - } - return this; - }; - - Try.prototype.compileNode = function(o) { - var catchPart, ensurePart, errorPart, tryPart; - o.indent += TAB; - errorPart = this.error ? " (" + (this.error.compile(o)) + ") " : ' '; - tryPart = this.attempt.compile(o, LEVEL_TOP); - catchPart = (function() { - var _ref2; - if (this.recovery) { - if (_ref2 = this.error.value, __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { - throw SyntaxError("catch variable may not be \"" + this.error.value + "\""); - } - if (!o.scope.check(this.error.value)) { - o.scope.add(this.error.value, 'param'); - } - return " catch" + errorPart + "{\n" + (this.recovery.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}"; - } else if (!(this.ensure || this.recovery)) { - return ' catch (_error) {}'; - } - }).call(this); - ensurePart = this.ensure ? " finally {\n" + (this.ensure.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}" : ''; - return "" + this.tab + "try {\n" + tryPart + "\n" + this.tab + "}" + (catchPart || '') + ensurePart; - }; - - return Try; - - })(Base); - - exports.Throw = Throw = (function(_super) { - - __extends(Throw, _super); - - function Throw(expression) { - this.expression = expression; - } - - Throw.prototype.children = ['expression']; - - Throw.prototype.isStatement = YES; - - Throw.prototype.jumps = NO; - - Throw.prototype.makeReturn = THIS; - - Throw.prototype.compileNode = function(o) { - return this.tab + ("throw " + (this.expression.compile(o)) + ";"); - }; - - return Throw; - - })(Base); - - exports.Existence = Existence = (function(_super) { - - __extends(Existence, _super); - - function Existence(expression) { - this.expression = expression; - } - - Existence.prototype.children = ['expression']; - - Existence.prototype.invert = NEGATE; - - Existence.prototype.compileNode = function(o) { - var cmp, cnj, code, _ref2; - this.expression.front = this.front; - code = this.expression.compile(o, LEVEL_OP); - if (IDENTIFIER.test(code) && !o.scope.check(code)) { - _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1]; - code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null"; - } else { - code = "" + code + " " + (this.negated ? '==' : '!=') + " null"; - } - if (o.level <= LEVEL_COND) { - return code; - } else { - return "(" + code + ")"; - } - }; - - return Existence; - - })(Base); - - exports.Parens = Parens = (function(_super) { - - __extends(Parens, _super); - - function Parens(body) { - this.body = body; - } - - Parens.prototype.children = ['body']; - - Parens.prototype.unwrap = function() { - return this.body; - }; - - Parens.prototype.isComplex = function() { - return this.body.isComplex(); - }; - - Parens.prototype.compileNode = function(o) { - var bare, code, expr; - expr = this.body.unwrap(); - if (expr instanceof Value && expr.isAtomic()) { - expr.front = this.front; - return expr.compile(o); - } - code = expr.compile(o, LEVEL_PAREN); - bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns)); - if (bare) { - return code; - } else { - return "(" + code + ")"; - } - }; - - return Parens; - - })(Base); - - exports.For = For = (function(_super) { - - __extends(For, _super); - - function For(body, source) { - var _ref2; - this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index; - this.body = Block.wrap([body]); - this.own = !!source.own; - this.object = !!source.object; - if (this.object) { - _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; - } - if (this.index instanceof Value) { - throw SyntaxError('index cannot be a pattern matching expression'); - } - this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; - this.pattern = this.name instanceof Value; - if (this.range && this.index) { - throw SyntaxError('indexes do not apply to range loops'); - } - if (this.range && this.pattern) { - throw SyntaxError('cannot pattern match over range loops'); - } - this.returns = false; - } - - For.prototype.children = ['body', 'source', 'guard', 'step']; - - For.prototype.compileNode = function(o) { - var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2; - body = Block.wrap([this.body]); - lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0; - if (lastJumps && lastJumps instanceof Return) { - this.returns = false; - } - source = this.range ? this.source.base : this.source; - scope = o.scope; - name = this.name && this.name.compile(o, LEVEL_LIST); - index = this.index && this.index.compile(o, LEVEL_LIST); - if (name && !this.pattern) { - scope.find(name); - } - if (index) { - scope.find(index); - } - if (this.returns) { - rvar = scope.freeVariable('results'); - } - ivar = (this.object && index) || scope.freeVariable('i'); - kvar = (this.range && name) || index || ivar; - kvarAssign = kvar !== ivar ? "" + kvar + " = " : ""; - if (this.step && !this.range) { - stepvar = scope.freeVariable("step"); - } - if (this.pattern) { - name = ivar; - } - varPart = ''; - guardPart = ''; - defPart = ''; - idt1 = this.tab + TAB; - if (this.range) { - forPart = source.compile(merge(o, { - index: ivar, - name: name, - step: this.step - })); - } else { - svar = this.source.compile(o, LEVEL_LIST); - if ((name || this.own) && !IDENTIFIER.test(svar)) { - defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; - svar = ref; - } - if (name && !this.pattern) { - namePart = "" + name + " = " + svar + "[" + kvar + "]"; - } - if (!this.object) { - lvar = scope.freeVariable('len'); - forVarPart = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length"; - if (this.step) { - forVarPart += ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP)); - } - stepPart = "" + kvarAssign + (this.step ? "" + ivar + " += " + stepvar : (kvar !== ivar ? "++" + ivar : "" + ivar + "++")); - forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart; - } - } - if (this.returns) { - resultPart = "" + this.tab + rvar + " = [];\n"; - returnResult = "\n" + this.tab + "return " + rvar + ";"; - body.makeReturn(rvar); - } - if (this.guard) { - if (body.expressions.length > 1) { - body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); - } else { - if (this.guard) { - body = Block.wrap([new If(this.guard, body)]); - } - } - } - if (this.pattern) { - body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]"))); - } - defPart += this.pluckDirectCall(o, body); - if (namePart) { - varPart = "\n" + idt1 + namePart + ";"; - } - if (this.object) { - forPart = "" + kvar + " in " + svar; - if (this.own) { - guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;"; - } - } - body = body.compile(merge(o, { - indent: idt1 - }), LEVEL_TOP); - if (body) { - body = '\n' + body + '\n'; - } - return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + varPart + body + this.tab + "}" + (returnResult || ''); - }; - - For.prototype.pluckDirectCall = function(o, body) { - var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; - defs = ''; - _ref2 = body.expressions; - for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) { - expr = _ref2[idx]; - expr = expr.unwrapAll(); - if (!(expr instanceof Call)) { - continue; - } - val = expr.variable.unwrapAll(); - if (!((val instanceof Code) || (val instanceof Value && ((_ref3 = val.base) != null ? _ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref4 = (_ref5 = val.properties[0].name) != null ? _ref5.value : void 0) === 'call' || _ref4 === 'apply')))) { - continue; - } - fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val; - ref = new Literal(o.scope.freeVariable('fn')); - base = new Value(ref); - if (val.base) { - _ref7 = [base, val], val.base = _ref7[0], base = _ref7[1]; - } - body.expressions[idx] = new Call(base, expr.args); - defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'; - } - return defs; - }; - - return For; - - })(While); - - exports.Switch = Switch = (function(_super) { - - __extends(Switch, _super); - - function Switch(subject, cases, otherwise) { - this.subject = subject; - this.cases = cases; - this.otherwise = otherwise; - } - - Switch.prototype.children = ['subject', 'cases', 'otherwise']; - - Switch.prototype.isStatement = YES; - - Switch.prototype.jumps = function(o) { - var block, conds, _i, _len, _ref2, _ref3, _ref4; - if (o == null) { - o = { - block: true - }; - } - _ref2 = this.cases; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1]; - if (block.jumps(o)) { - return block; - } - } - return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0; - }; - - Switch.prototype.makeReturn = function(res) { - var pair, _i, _len, _ref2, _ref3; - _ref2 = this.cases; - for (_i = 0, _len = _ref2.length; _i < _len; _i++) { - pair = _ref2[_i]; - pair[1].makeReturn(res); - } - if (res) { - this.otherwise || (this.otherwise = new Block([new Literal('void 0')])); - } - if ((_ref3 = this.otherwise) != null) { - _ref3.makeReturn(res); - } - return this; - }; - - Switch.prototype.compileNode = function(o) { - var block, body, code, cond, conditions, expr, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4, _ref5; - idt1 = o.indent + TAB; - idt2 = o.indent = idt1 + TAB; - code = this.tab + ("switch (" + (((_ref2 = this.subject) != null ? _ref2.compile(o, LEVEL_PAREN) : void 0) || false) + ") {\n"); - _ref3 = this.cases; - for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) { - _ref4 = _ref3[i], conditions = _ref4[0], block = _ref4[1]; - _ref5 = flatten([conditions]); - for (_j = 0, _len1 = _ref5.length; _j < _len1; _j++) { - cond = _ref5[_j]; - if (!this.subject) { - cond = cond.invert(); - } - code += idt1 + ("case " + (cond.compile(o, LEVEL_PAREN)) + ":\n"); - } - if (body = block.compile(o, LEVEL_TOP)) { - code += body + '\n'; - } - if (i === this.cases.length - 1 && !this.otherwise) { - break; - } - expr = this.lastNonComment(block.expressions); - if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) { - continue; - } - code += idt2 + 'break;\n'; - } - if (this.otherwise && this.otherwise.expressions.length) { - code += idt1 + ("default:\n" + (this.otherwise.compile(o, LEVEL_TOP)) + "\n"); - } - return code + this.tab + '}'; - }; - - return Switch; - - })(Base); - - exports.If = If = (function(_super) { - - __extends(If, _super); - - function If(condition, body, options) { - this.body = body; - if (options == null) { - options = {}; - } - this.condition = options.type === 'unless' ? condition.invert() : condition; - this.elseBody = null; - this.isChain = false; - this.soak = options.soak; - } - - If.prototype.children = ['condition', 'body', 'elseBody']; - - If.prototype.bodyNode = function() { - var _ref2; - return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0; - }; - - If.prototype.elseBodyNode = function() { - var _ref2; - return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0; - }; - - If.prototype.addElse = function(elseBody) { - if (this.isChain) { - this.elseBodyNode().addElse(elseBody); - } else { - this.isChain = elseBody instanceof If; - this.elseBody = this.ensureBlock(elseBody); - } - return this; - }; - - If.prototype.isStatement = function(o) { - var _ref2; - return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0); - }; - - If.prototype.jumps = function(o) { - var _ref2; - return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0); - }; - - If.prototype.compileNode = function(o) { - if (this.isStatement(o)) { - return this.compileStatement(o); - } else { - return this.compileExpression(o); - } - }; - - If.prototype.makeReturn = function(res) { - if (res) { - this.elseBody || (this.elseBody = new Block([new Literal('void 0')])); - } - this.body && (this.body = new Block([this.body.makeReturn(res)])); - this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)])); - return this; - }; - - If.prototype.ensureBlock = function(node) { - if (node instanceof Block) { - return node; - } else { - return new Block([node]); - } - }; - - If.prototype.compileStatement = function(o) { - var body, child, cond, exeq, ifPart; - child = del(o, 'chainChild'); - exeq = del(o, 'isExistentialEquals'); - if (exeq) { - return new If(this.condition.invert(), this.elseBodyNode(), { - type: 'if' - }).compile(o); - } - cond = this.condition.compile(o, LEVEL_PAREN); - o.indent += TAB; - body = this.ensureBlock(this.body); - ifPart = "if (" + cond + ") {\n" + (body.compile(o)) + "\n" + this.tab + "}"; - if (!child) { - ifPart = this.tab + ifPart; - } - if (!this.elseBody) { - return ifPart; - } - return ifPart + ' else ' + (this.isChain ? (o.indent = this.tab, o.chainChild = true, this.elseBody.unwrap().compile(o, LEVEL_TOP)) : "{\n" + (this.elseBody.compile(o, LEVEL_TOP)) + "\n" + this.tab + "}"); - }; - - If.prototype.compileExpression = function(o) { - var alt, body, code, cond; - cond = this.condition.compile(o, LEVEL_COND); - body = this.bodyNode().compile(o, LEVEL_LIST); - alt = this.elseBodyNode() ? this.elseBodyNode().compile(o, LEVEL_LIST) : 'void 0'; - code = "" + cond + " ? " + body + " : " + alt; - if (o.level >= LEVEL_COND) { - return "(" + code + ")"; - } else { - return code; - } - }; - - If.prototype.unfoldSoak = function() { - return this.soak && this; - }; - - return If; - - })(Base); - - Closure = { - wrap: function(expressions, statement, noReturn) { - var args, call, func, mentionsArgs, meth; - if (expressions.jumps()) { - return expressions; - } - func = new Code([], Block.wrap([expressions])); - args = []; - if ((mentionsArgs = expressions.contains(this.literalArgs)) || expressions.contains(this.literalThis)) { - meth = new Literal(mentionsArgs ? 'apply' : 'call'); - args = [new Literal('this')]; - if (mentionsArgs) { - args.push(new Literal('arguments')); - } - func = new Value(func, [new Access(meth)]); - } - func.noReturn = noReturn; - call = new Call(func, args); - if (statement) { - return Block.wrap([call]); - } else { - return call; - } - }, - literalArgs: function(node) { - return node instanceof Literal && node.value === 'arguments' && !node.asKey; - }, - literalThis: function(node) { - return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper); - } - }; - - unfoldSoak = function(o, parent, name) { - var ifn; - if (!(ifn = parent[name].unfoldSoak(o))) { - return; - } - parent[name] = ifn.body; - ifn.body = new Value(parent); - return ifn; - }; - - UTILITIES = { - "extends": function() { - return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }"; - }, - bind: function() { - return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }'; - }, - indexOf: function() { - return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }"; - }, - hasProp: function() { - return '{}.hasOwnProperty'; - }, - slice: function() { - return '[].slice'; - } - }; - - LEVEL_TOP = 1; - - LEVEL_PAREN = 2; - - LEVEL_LIST = 3; - - LEVEL_COND = 4; - - LEVEL_OP = 5; - - LEVEL_ACCESS = 6; - - TAB = ' '; - - IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*"; - - IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$"); - - SIMPLENUM = /^[+-]?\d+$/; - - METHOD_DEF = RegExp("^(?:(" + IDENTIFIER_STR + ")\\.prototype(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\]))|(" + IDENTIFIER_STR + ")$"); - - IS_STRING = /^['"]/; - - utility = function(name) { - var ref; - ref = "__" + name; - Scope.root.assign(ref, UTILITIES[name]()); - return ref; - }; - - multident = function(code, tab) { - code = code.replace(/\n/g, '$&' + tab); - return code.replace(/\s+$/, ''); - }; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js deleted file mode 100644 index d7fda40a..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/optparse.js +++ /dev/null @@ -1,138 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments; - - exports.OptionParser = OptionParser = (function() { - - function OptionParser(rules, banner) { - this.banner = banner; - this.rules = buildRules(rules); - } - - OptionParser.prototype.parse = function(args) { - var arg, i, isOption, matchedRule, options, originalArgs, pos, rule, seenNonOptionArg, skippingArgument, value, _i, _j, _len, _len1, _ref; - options = { - "arguments": [] - }; - skippingArgument = false; - originalArgs = args; - args = normalizeArguments(args); - for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { - arg = args[i]; - if (skippingArgument) { - skippingArgument = false; - continue; - } - if (arg === '--') { - pos = originalArgs.indexOf('--'); - options["arguments"] = options["arguments"].concat(originalArgs.slice(pos + 1)); - break; - } - isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG)); - seenNonOptionArg = options["arguments"].length > 0; - if (!seenNonOptionArg) { - matchedRule = false; - _ref = this.rules; - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - rule = _ref[_j]; - if (rule.shortFlag === arg || rule.longFlag === arg) { - value = true; - if (rule.hasArgument) { - skippingArgument = true; - value = args[i + 1]; - } - options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value; - matchedRule = true; - break; - } - } - if (isOption && !matchedRule) { - throw new Error("unrecognized option: " + arg); - } - } - if (seenNonOptionArg || !isOption) { - options["arguments"].push(arg); - } - } - return options; - }; - - OptionParser.prototype.help = function() { - var letPart, lines, rule, spaces, _i, _len, _ref; - lines = []; - if (this.banner) { - lines.unshift("" + this.banner + "\n"); - } - _ref = this.rules; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - rule = _ref[_i]; - spaces = 15 - rule.longFlag.length; - spaces = spaces > 0 ? Array(spaces + 1).join(' ') : ''; - letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' '; - lines.push(' ' + letPart + rule.longFlag + spaces + rule.description); - } - return "\n" + (lines.join('\n')) + "\n"; - }; - - return OptionParser; - - })(); - - LONG_FLAG = /^(--\w[\w\-]*)/; - - SHORT_FLAG = /^(-\w)$/; - - MULTI_FLAG = /^-(\w{2,})/; - - OPTIONAL = /\[(\w+(\*?))\]/; - - buildRules = function(rules) { - var tuple, _i, _len, _results; - _results = []; - for (_i = 0, _len = rules.length; _i < _len; _i++) { - tuple = rules[_i]; - if (tuple.length < 3) { - tuple.unshift(null); - } - _results.push(buildRule.apply(null, tuple)); - } - return _results; - }; - - buildRule = function(shortFlag, longFlag, description, options) { - var match; - if (options == null) { - options = {}; - } - match = longFlag.match(OPTIONAL); - longFlag = longFlag.match(LONG_FLAG)[1]; - return { - name: longFlag.substr(2), - shortFlag: shortFlag, - longFlag: longFlag, - description: description, - hasArgument: !!(match && match[1]), - isList: !!(match && match[2]) - }; - }; - - normalizeArguments = function(args) { - var arg, l, match, result, _i, _j, _len, _len1, _ref; - args = args.slice(0); - result = []; - for (_i = 0, _len = args.length; _i < _len; _i++) { - arg = args[_i]; - if (match = arg.match(MULTI_FLAG)) { - _ref = match[1].split(''); - for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { - l = _ref[_j]; - result.push('-' + l); - } - } else { - result.push(arg); - } - } - return result; - }; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js deleted file mode 100755 index f0499038..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/parser.js +++ /dev/null @@ -1,683 +0,0 @@ -/* Jison generated parser */ -var parser = (function(){ -var parser = {trace: function trace() { }, -yy: {}, -symbols_: {"error":2,"Root":3,"Body":4,"Block":5,"TERMINATOR":6,"Line":7,"Expression":8,"Statement":9,"Return":10,"Comment":11,"STATEMENT":12,"Value":13,"Invocation":14,"Code":15,"Operation":16,"Assign":17,"If":18,"Try":19,"While":20,"For":21,"Switch":22,"Class":23,"Throw":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"DEBUGGER":35,"UNDEFINED":36,"NULL":37,"BOOL":38,"Assignable":39,"=":40,"AssignObj":41,"ObjAssignable":42,":":43,"ThisProperty":44,"RETURN":45,"HERECOMMENT":46,"PARAM_START":47,"ParamList":48,"PARAM_END":49,"FuncGlyph":50,"->":51,"=>":52,"OptComma":53,",":54,"Param":55,"ParamVar":56,"...":57,"Array":58,"Object":59,"Splat":60,"SimpleAssignable":61,"Accessor":62,"Parenthetical":63,"Range":64,"This":65,".":66,"?.":67,"::":68,"Index":69,"INDEX_START":70,"IndexValue":71,"INDEX_END":72,"INDEX_SOAK":73,"Slice":74,"{":75,"AssignList":76,"}":77,"CLASS":78,"EXTENDS":79,"OptFuncExist":80,"Arguments":81,"SUPER":82,"FUNC_EXIST":83,"CALL_START":84,"CALL_END":85,"ArgList":86,"THIS":87,"@":88,"[":89,"]":90,"RangeDots":91,"..":92,"Arg":93,"SimpleArgs":94,"TRY":95,"Catch":96,"FINALLY":97,"CATCH":98,"THROW":99,"(":100,")":101,"WhileSource":102,"WHILE":103,"WHEN":104,"UNTIL":105,"Loop":106,"LOOP":107,"ForBody":108,"FOR":109,"ForStart":110,"ForSource":111,"ForVariables":112,"OWN":113,"ForValue":114,"FORIN":115,"FOROF":116,"BY":117,"SWITCH":118,"Whens":119,"ELSE":120,"When":121,"LEADING_WHEN":122,"IfBlock":123,"IF":124,"POST_IF":125,"UNARY":126,"-":127,"+":128,"--":129,"++":130,"?":131,"MATH":132,"SHIFT":133,"COMPARE":134,"LOGIC":135,"RELATION":136,"COMPOUND_ASSIGN":137,"$accept":0,"$end":1}, -terminals_: {2:"error",6:"TERMINATOR",12:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"UNDEFINED",37:"NULL",38:"BOOL",40:"=",43:":",45:"RETURN",46:"HERECOMMENT",47:"PARAM_START",49:"PARAM_END",51:"->",52:"=>",54:",",57:"...",66:".",67:"?.",68:"::",70:"INDEX_START",72:"INDEX_END",73:"INDEX_SOAK",75:"{",77:"}",78:"CLASS",79:"EXTENDS",82:"SUPER",83:"FUNC_EXIST",84:"CALL_START",85:"CALL_END",87:"THIS",88:"@",89:"[",90:"]",92:"..",95:"TRY",97:"FINALLY",98:"CATCH",99:"THROW",100:"(",101:")",103:"WHILE",104:"WHEN",105:"UNTIL",107:"LOOP",109:"FOR",113:"OWN",115:"FORIN",116:"FOROF",117:"BY",118:"SWITCH",120:"ELSE",122:"LEADING_WHEN",124:"IF",125:"POST_IF",126:"UNARY",127:"-",128:"+",129:"--",130:"++",131:"?",132:"MATH",133:"SHIFT",134:"COMPARE",135:"LOGIC",136:"RELATION",137:"COMPOUND_ASSIGN"}, -productions_: [0,[3,0],[3,1],[3,2],[4,1],[4,3],[4,2],[7,1],[7,1],[9,1],[9,1],[9,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[8,1],[5,2],[5,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[17,3],[17,4],[17,5],[41,1],[41,3],[41,5],[41,1],[42,1],[42,1],[42,1],[10,2],[10,1],[11,1],[15,5],[15,2],[50,1],[50,1],[53,0],[53,1],[48,0],[48,1],[48,3],[48,4],[48,6],[55,1],[55,2],[55,3],[56,1],[56,1],[56,1],[56,1],[60,2],[61,1],[61,2],[61,2],[61,1],[39,1],[39,1],[39,1],[13,1],[13,1],[13,1],[13,1],[13,1],[62,2],[62,2],[62,2],[62,1],[62,1],[69,3],[69,2],[71,1],[71,1],[59,4],[76,0],[76,1],[76,3],[76,4],[76,6],[23,1],[23,2],[23,3],[23,4],[23,2],[23,3],[23,4],[23,5],[14,3],[14,3],[14,1],[14,2],[80,0],[80,1],[81,2],[81,4],[65,1],[65,1],[44,2],[58,2],[58,4],[91,1],[91,1],[64,5],[74,3],[74,2],[74,2],[74,1],[86,1],[86,3],[86,4],[86,4],[86,6],[93,1],[93,1],[94,1],[94,3],[19,2],[19,3],[19,4],[19,5],[96,3],[24,2],[63,3],[63,5],[102,2],[102,4],[102,2],[102,4],[20,2],[20,2],[20,2],[20,1],[106,2],[106,2],[21,2],[21,2],[21,2],[108,2],[108,2],[110,2],[110,3],[114,1],[114,1],[114,1],[114,1],[112,1],[112,3],[111,2],[111,2],[111,4],[111,4],[111,4],[111,6],[111,6],[22,5],[22,7],[22,4],[22,6],[119,1],[119,2],[121,3],[121,4],[123,3],[123,5],[18,1],[18,3],[18,3],[18,3],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,2],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,3],[16,5],[16,3]], -performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { - -var $0 = $$.length - 1; -switch (yystate) { -case 1:return this.$ = new yy.Block; -break; -case 2:return this.$ = $$[$0]; -break; -case 3:return this.$ = $$[$0-1]; -break; -case 4:this.$ = yy.Block.wrap([$$[$0]]); -break; -case 5:this.$ = $$[$0-2].push($$[$0]); -break; -case 6:this.$ = $$[$0-1]; -break; -case 7:this.$ = $$[$0]; -break; -case 8:this.$ = $$[$0]; -break; -case 9:this.$ = $$[$0]; -break; -case 10:this.$ = $$[$0]; -break; -case 11:this.$ = new yy.Literal($$[$0]); -break; -case 12:this.$ = $$[$0]; -break; -case 13:this.$ = $$[$0]; -break; -case 14:this.$ = $$[$0]; -break; -case 15:this.$ = $$[$0]; -break; -case 16:this.$ = $$[$0]; -break; -case 17:this.$ = $$[$0]; -break; -case 18:this.$ = $$[$0]; -break; -case 19:this.$ = $$[$0]; -break; -case 20:this.$ = $$[$0]; -break; -case 21:this.$ = $$[$0]; -break; -case 22:this.$ = $$[$0]; -break; -case 23:this.$ = $$[$0]; -break; -case 24:this.$ = new yy.Block; -break; -case 25:this.$ = $$[$0-1]; -break; -case 26:this.$ = new yy.Literal($$[$0]); -break; -case 27:this.$ = new yy.Literal($$[$0]); -break; -case 28:this.$ = new yy.Literal($$[$0]); -break; -case 29:this.$ = $$[$0]; -break; -case 30:this.$ = new yy.Literal($$[$0]); -break; -case 31:this.$ = new yy.Literal($$[$0]); -break; -case 32:this.$ = new yy.Literal($$[$0]); -break; -case 33:this.$ = new yy.Undefined; -break; -case 34:this.$ = new yy.Null; -break; -case 35:this.$ = new yy.Bool($$[$0]); -break; -case 36:this.$ = new yy.Assign($$[$0-2], $$[$0]); -break; -case 37:this.$ = new yy.Assign($$[$0-3], $$[$0]); -break; -case 38:this.$ = new yy.Assign($$[$0-4], $$[$0-1]); -break; -case 39:this.$ = new yy.Value($$[$0]); -break; -case 40:this.$ = new yy.Assign(new yy.Value($$[$0-2]), $$[$0], 'object'); -break; -case 41:this.$ = new yy.Assign(new yy.Value($$[$0-4]), $$[$0-1], 'object'); -break; -case 42:this.$ = $$[$0]; -break; -case 43:this.$ = $$[$0]; -break; -case 44:this.$ = $$[$0]; -break; -case 45:this.$ = $$[$0]; -break; -case 46:this.$ = new yy.Return($$[$0]); -break; -case 47:this.$ = new yy.Return; -break; -case 48:this.$ = new yy.Comment($$[$0]); -break; -case 49:this.$ = new yy.Code($$[$0-3], $$[$0], $$[$0-1]); -break; -case 50:this.$ = new yy.Code([], $$[$0], $$[$0-1]); -break; -case 51:this.$ = 'func'; -break; -case 52:this.$ = 'boundfunc'; -break; -case 53:this.$ = $$[$0]; -break; -case 54:this.$ = $$[$0]; -break; -case 55:this.$ = []; -break; -case 56:this.$ = [$$[$0]]; -break; -case 57:this.$ = $$[$0-2].concat($$[$0]); -break; -case 58:this.$ = $$[$0-3].concat($$[$0]); -break; -case 59:this.$ = $$[$0-5].concat($$[$0-2]); -break; -case 60:this.$ = new yy.Param($$[$0]); -break; -case 61:this.$ = new yy.Param($$[$0-1], null, true); -break; -case 62:this.$ = new yy.Param($$[$0-2], $$[$0]); -break; -case 63:this.$ = $$[$0]; -break; -case 64:this.$ = $$[$0]; -break; -case 65:this.$ = $$[$0]; -break; -case 66:this.$ = $$[$0]; -break; -case 67:this.$ = new yy.Splat($$[$0-1]); -break; -case 68:this.$ = new yy.Value($$[$0]); -break; -case 69:this.$ = $$[$0-1].add($$[$0]); -break; -case 70:this.$ = new yy.Value($$[$0-1], [].concat($$[$0])); -break; -case 71:this.$ = $$[$0]; -break; -case 72:this.$ = $$[$0]; -break; -case 73:this.$ = new yy.Value($$[$0]); -break; -case 74:this.$ = new yy.Value($$[$0]); -break; -case 75:this.$ = $$[$0]; -break; -case 76:this.$ = new yy.Value($$[$0]); -break; -case 77:this.$ = new yy.Value($$[$0]); -break; -case 78:this.$ = new yy.Value($$[$0]); -break; -case 79:this.$ = $$[$0]; -break; -case 80:this.$ = new yy.Access($$[$0]); -break; -case 81:this.$ = new yy.Access($$[$0], 'soak'); -break; -case 82:this.$ = [new yy.Access(new yy.Literal('prototype')), new yy.Access($$[$0])]; -break; -case 83:this.$ = new yy.Access(new yy.Literal('prototype')); -break; -case 84:this.$ = $$[$0]; -break; -case 85:this.$ = $$[$0-1]; -break; -case 86:this.$ = yy.extend($$[$0], { - soak: true - }); -break; -case 87:this.$ = new yy.Index($$[$0]); -break; -case 88:this.$ = new yy.Slice($$[$0]); -break; -case 89:this.$ = new yy.Obj($$[$0-2], $$[$0-3].generated); -break; -case 90:this.$ = []; -break; -case 91:this.$ = [$$[$0]]; -break; -case 92:this.$ = $$[$0-2].concat($$[$0]); -break; -case 93:this.$ = $$[$0-3].concat($$[$0]); -break; -case 94:this.$ = $$[$0-5].concat($$[$0-2]); -break; -case 95:this.$ = new yy.Class; -break; -case 96:this.$ = new yy.Class(null, null, $$[$0]); -break; -case 97:this.$ = new yy.Class(null, $$[$0]); -break; -case 98:this.$ = new yy.Class(null, $$[$0-1], $$[$0]); -break; -case 99:this.$ = new yy.Class($$[$0]); -break; -case 100:this.$ = new yy.Class($$[$0-1], null, $$[$0]); -break; -case 101:this.$ = new yy.Class($$[$0-2], $$[$0]); -break; -case 102:this.$ = new yy.Class($$[$0-3], $$[$0-1], $$[$0]); -break; -case 103:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]); -break; -case 104:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]); -break; -case 105:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]); -break; -case 106:this.$ = new yy.Call('super', $$[$0]); -break; -case 107:this.$ = false; -break; -case 108:this.$ = true; -break; -case 109:this.$ = []; -break; -case 110:this.$ = $$[$0-2]; -break; -case 111:this.$ = new yy.Value(new yy.Literal('this')); -break; -case 112:this.$ = new yy.Value(new yy.Literal('this')); -break; -case 113:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Access($$[$0])], 'this'); -break; -case 114:this.$ = new yy.Arr([]); -break; -case 115:this.$ = new yy.Arr($$[$0-2]); -break; -case 116:this.$ = 'inclusive'; -break; -case 117:this.$ = 'exclusive'; -break; -case 118:this.$ = new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]); -break; -case 119:this.$ = new yy.Range($$[$0-2], $$[$0], $$[$0-1]); -break; -case 120:this.$ = new yy.Range($$[$0-1], null, $$[$0]); -break; -case 121:this.$ = new yy.Range(null, $$[$0], $$[$0-1]); -break; -case 122:this.$ = new yy.Range(null, null, $$[$0]); -break; -case 123:this.$ = [$$[$0]]; -break; -case 124:this.$ = $$[$0-2].concat($$[$0]); -break; -case 125:this.$ = $$[$0-3].concat($$[$0]); -break; -case 126:this.$ = $$[$0-2]; -break; -case 127:this.$ = $$[$0-5].concat($$[$0-2]); -break; -case 128:this.$ = $$[$0]; -break; -case 129:this.$ = $$[$0]; -break; -case 130:this.$ = $$[$0]; -break; -case 131:this.$ = [].concat($$[$0-2], $$[$0]); -break; -case 132:this.$ = new yy.Try($$[$0]); -break; -case 133:this.$ = new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]); -break; -case 134:this.$ = new yy.Try($$[$0-2], null, null, $$[$0]); -break; -case 135:this.$ = new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]); -break; -case 136:this.$ = [$$[$0-1], $$[$0]]; -break; -case 137:this.$ = new yy.Throw($$[$0]); -break; -case 138:this.$ = new yy.Parens($$[$0-1]); -break; -case 139:this.$ = new yy.Parens($$[$0-2]); -break; -case 140:this.$ = new yy.While($$[$0]); -break; -case 141:this.$ = new yy.While($$[$0-2], { - guard: $$[$0] - }); -break; -case 142:this.$ = new yy.While($$[$0], { - invert: true - }); -break; -case 143:this.$ = new yy.While($$[$0-2], { - invert: true, - guard: $$[$0] - }); -break; -case 144:this.$ = $$[$0-1].addBody($$[$0]); -break; -case 145:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]])); -break; -case 146:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]])); -break; -case 147:this.$ = $$[$0]; -break; -case 148:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]); -break; -case 149:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]])); -break; -case 150:this.$ = new yy.For($$[$0-1], $$[$0]); -break; -case 151:this.$ = new yy.For($$[$0-1], $$[$0]); -break; -case 152:this.$ = new yy.For($$[$0], $$[$0-1]); -break; -case 153:this.$ = { - source: new yy.Value($$[$0]) - }; -break; -case 154:this.$ = (function () { - $$[$0].own = $$[$0-1].own; - $$[$0].name = $$[$0-1][0]; - $$[$0].index = $$[$0-1][1]; - return $$[$0]; - }()); -break; -case 155:this.$ = $$[$0]; -break; -case 156:this.$ = (function () { - $$[$0].own = true; - return $$[$0]; - }()); -break; -case 157:this.$ = $$[$0]; -break; -case 158:this.$ = $$[$0]; -break; -case 159:this.$ = new yy.Value($$[$0]); -break; -case 160:this.$ = new yy.Value($$[$0]); -break; -case 161:this.$ = [$$[$0]]; -break; -case 162:this.$ = [$$[$0-2], $$[$0]]; -break; -case 163:this.$ = { - source: $$[$0] - }; -break; -case 164:this.$ = { - source: $$[$0], - object: true - }; -break; -case 165:this.$ = { - source: $$[$0-2], - guard: $$[$0] - }; -break; -case 166:this.$ = { - source: $$[$0-2], - guard: $$[$0], - object: true - }; -break; -case 167:this.$ = { - source: $$[$0-2], - step: $$[$0] - }; -break; -case 168:this.$ = { - source: $$[$0-4], - guard: $$[$0-2], - step: $$[$0] - }; -break; -case 169:this.$ = { - source: $$[$0-4], - step: $$[$0-2], - guard: $$[$0] - }; -break; -case 170:this.$ = new yy.Switch($$[$0-3], $$[$0-1]); -break; -case 171:this.$ = new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]); -break; -case 172:this.$ = new yy.Switch(null, $$[$0-1]); -break; -case 173:this.$ = new yy.Switch(null, $$[$0-3], $$[$0-1]); -break; -case 174:this.$ = $$[$0]; -break; -case 175:this.$ = $$[$0-1].concat($$[$0]); -break; -case 176:this.$ = [[$$[$0-1], $$[$0]]]; -break; -case 177:this.$ = [[$$[$0-2], $$[$0-1]]]; -break; -case 178:this.$ = new yy.If($$[$0-1], $$[$0], { - type: $$[$0-2] - }); -break; -case 179:this.$ = $$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], { - type: $$[$0-2] - })); -break; -case 180:this.$ = $$[$0]; -break; -case 181:this.$ = $$[$0-2].addElse($$[$0]); -break; -case 182:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), { - type: $$[$0-1], - statement: true - }); -break; -case 183:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), { - type: $$[$0-1], - statement: true - }); -break; -case 184:this.$ = new yy.Op($$[$0-1], $$[$0]); -break; -case 185:this.$ = new yy.Op('-', $$[$0]); -break; -case 186:this.$ = new yy.Op('+', $$[$0]); -break; -case 187:this.$ = new yy.Op('--', $$[$0]); -break; -case 188:this.$ = new yy.Op('++', $$[$0]); -break; -case 189:this.$ = new yy.Op('--', $$[$0-1], null, true); -break; -case 190:this.$ = new yy.Op('++', $$[$0-1], null, true); -break; -case 191:this.$ = new yy.Existence($$[$0-1]); -break; -case 192:this.$ = new yy.Op('+', $$[$0-2], $$[$0]); -break; -case 193:this.$ = new yy.Op('-', $$[$0-2], $$[$0]); -break; -case 194:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 195:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 196:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 197:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]); -break; -case 198:this.$ = (function () { - if ($$[$0-1].charAt(0) === '!') { - return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert(); - } else { - return new yy.Op($$[$0-1], $$[$0-2], $$[$0]); - } - }()); -break; -case 199:this.$ = new yy.Assign($$[$0-2], $$[$0], $$[$0-1]); -break; -case 200:this.$ = new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]); -break; -case 201:this.$ = new yy.Extends($$[$0-2], $$[$0]); -break; -} -}, -table: [{1:[2,1],3:1,4:2,5:3,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[3]},{1:[2,2],6:[1,74]},{6:[1,75]},{1:[2,4],6:[2,4],26:[2,4],101:[2,4]},{4:77,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[1,76],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,7],6:[2,7],26:[2,7],101:[2,7],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,8],6:[2,8],26:[2,8],101:[2,8],102:90,103:[1,65],105:[1,66],108:91,109:[1,68],110:69,125:[1,89]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],49:[2,12],54:[2,12],57:[2,12],62:93,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],72:[2,12],73:[1,100],77:[2,12],80:92,83:[1,94],84:[2,107],85:[2,12],90:[2,12],92:[2,12],101:[2,12],103:[2,12],104:[2,12],105:[2,12],109:[2,12],117:[2,12],125:[2,12],127:[2,12],128:[2,12],131:[2,12],132:[2,12],133:[2,12],134:[2,12],135:[2,12],136:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],49:[2,13],54:[2,13],57:[2,13],62:102,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],72:[2,13],73:[1,100],77:[2,13],80:101,83:[1,94],84:[2,107],85:[2,13],90:[2,13],92:[2,13],101:[2,13],103:[2,13],104:[2,13],105:[2,13],109:[2,13],117:[2,13],125:[2,13],127:[2,13],128:[2,13],131:[2,13],132:[2,13],133:[2,13],134:[2,13],135:[2,13],136:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],49:[2,14],54:[2,14],57:[2,14],72:[2,14],77:[2,14],85:[2,14],90:[2,14],92:[2,14],101:[2,14],103:[2,14],104:[2,14],105:[2,14],109:[2,14],117:[2,14],125:[2,14],127:[2,14],128:[2,14],131:[2,14],132:[2,14],133:[2,14],134:[2,14],135:[2,14],136:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],49:[2,15],54:[2,15],57:[2,15],72:[2,15],77:[2,15],85:[2,15],90:[2,15],92:[2,15],101:[2,15],103:[2,15],104:[2,15],105:[2,15],109:[2,15],117:[2,15],125:[2,15],127:[2,15],128:[2,15],131:[2,15],132:[2,15],133:[2,15],134:[2,15],135:[2,15],136:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],49:[2,16],54:[2,16],57:[2,16],72:[2,16],77:[2,16],85:[2,16],90:[2,16],92:[2,16],101:[2,16],103:[2,16],104:[2,16],105:[2,16],109:[2,16],117:[2,16],125:[2,16],127:[2,16],128:[2,16],131:[2,16],132:[2,16],133:[2,16],134:[2,16],135:[2,16],136:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],49:[2,17],54:[2,17],57:[2,17],72:[2,17],77:[2,17],85:[2,17],90:[2,17],92:[2,17],101:[2,17],103:[2,17],104:[2,17],105:[2,17],109:[2,17],117:[2,17],125:[2,17],127:[2,17],128:[2,17],131:[2,17],132:[2,17],133:[2,17],134:[2,17],135:[2,17],136:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],49:[2,18],54:[2,18],57:[2,18],72:[2,18],77:[2,18],85:[2,18],90:[2,18],92:[2,18],101:[2,18],103:[2,18],104:[2,18],105:[2,18],109:[2,18],117:[2,18],125:[2,18],127:[2,18],128:[2,18],131:[2,18],132:[2,18],133:[2,18],134:[2,18],135:[2,18],136:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],49:[2,19],54:[2,19],57:[2,19],72:[2,19],77:[2,19],85:[2,19],90:[2,19],92:[2,19],101:[2,19],103:[2,19],104:[2,19],105:[2,19],109:[2,19],117:[2,19],125:[2,19],127:[2,19],128:[2,19],131:[2,19],132:[2,19],133:[2,19],134:[2,19],135:[2,19],136:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],49:[2,20],54:[2,20],57:[2,20],72:[2,20],77:[2,20],85:[2,20],90:[2,20],92:[2,20],101:[2,20],103:[2,20],104:[2,20],105:[2,20],109:[2,20],117:[2,20],125:[2,20],127:[2,20],128:[2,20],131:[2,20],132:[2,20],133:[2,20],134:[2,20],135:[2,20],136:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],49:[2,21],54:[2,21],57:[2,21],72:[2,21],77:[2,21],85:[2,21],90:[2,21],92:[2,21],101:[2,21],103:[2,21],104:[2,21],105:[2,21],109:[2,21],117:[2,21],125:[2,21],127:[2,21],128:[2,21],131:[2,21],132:[2,21],133:[2,21],134:[2,21],135:[2,21],136:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],49:[2,22],54:[2,22],57:[2,22],72:[2,22],77:[2,22],85:[2,22],90:[2,22],92:[2,22],101:[2,22],103:[2,22],104:[2,22],105:[2,22],109:[2,22],117:[2,22],125:[2,22],127:[2,22],128:[2,22],131:[2,22],132:[2,22],133:[2,22],134:[2,22],135:[2,22],136:[2,22]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],49:[2,23],54:[2,23],57:[2,23],72:[2,23],77:[2,23],85:[2,23],90:[2,23],92:[2,23],101:[2,23],103:[2,23],104:[2,23],105:[2,23],109:[2,23],117:[2,23],125:[2,23],127:[2,23],128:[2,23],131:[2,23],132:[2,23],133:[2,23],134:[2,23],135:[2,23],136:[2,23]},{1:[2,9],6:[2,9],26:[2,9],101:[2,9],103:[2,9],105:[2,9],109:[2,9],125:[2,9]},{1:[2,10],6:[2,10],26:[2,10],101:[2,10],103:[2,10],105:[2,10],109:[2,10],125:[2,10]},{1:[2,11],6:[2,11],26:[2,11],101:[2,11],103:[2,11],105:[2,11],109:[2,11],125:[2,11]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],40:[1,103],49:[2,75],54:[2,75],57:[2,75],66:[2,75],67:[2,75],68:[2,75],70:[2,75],72:[2,75],73:[2,75],77:[2,75],83:[2,75],84:[2,75],85:[2,75],90:[2,75],92:[2,75],101:[2,75],103:[2,75],104:[2,75],105:[2,75],109:[2,75],117:[2,75],125:[2,75],127:[2,75],128:[2,75],131:[2,75],132:[2,75],133:[2,75],134:[2,75],135:[2,75],136:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],49:[2,76],54:[2,76],57:[2,76],66:[2,76],67:[2,76],68:[2,76],70:[2,76],72:[2,76],73:[2,76],77:[2,76],83:[2,76],84:[2,76],85:[2,76],90:[2,76],92:[2,76],101:[2,76],103:[2,76],104:[2,76],105:[2,76],109:[2,76],117:[2,76],125:[2,76],127:[2,76],128:[2,76],131:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76],136:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],49:[2,77],54:[2,77],57:[2,77],66:[2,77],67:[2,77],68:[2,77],70:[2,77],72:[2,77],73:[2,77],77:[2,77],83:[2,77],84:[2,77],85:[2,77],90:[2,77],92:[2,77],101:[2,77],103:[2,77],104:[2,77],105:[2,77],109:[2,77],117:[2,77],125:[2,77],127:[2,77],128:[2,77],131:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77],136:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],49:[2,78],54:[2,78],57:[2,78],66:[2,78],67:[2,78],68:[2,78],70:[2,78],72:[2,78],73:[2,78],77:[2,78],83:[2,78],84:[2,78],85:[2,78],90:[2,78],92:[2,78],101:[2,78],103:[2,78],104:[2,78],105:[2,78],109:[2,78],117:[2,78],125:[2,78],127:[2,78],128:[2,78],131:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78],136:[2,78]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],49:[2,79],54:[2,79],57:[2,79],66:[2,79],67:[2,79],68:[2,79],70:[2,79],72:[2,79],73:[2,79],77:[2,79],83:[2,79],84:[2,79],85:[2,79],90:[2,79],92:[2,79],101:[2,79],103:[2,79],104:[2,79],105:[2,79],109:[2,79],117:[2,79],125:[2,79],127:[2,79],128:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79],136:[2,79]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],49:[2,105],54:[2,105],57:[2,105],66:[2,105],67:[2,105],68:[2,105],70:[2,105],72:[2,105],73:[2,105],77:[2,105],81:104,83:[2,105],84:[1,105],85:[2,105],90:[2,105],92:[2,105],101:[2,105],103:[2,105],104:[2,105],105:[2,105],109:[2,105],117:[2,105],125:[2,105],127:[2,105],128:[2,105],131:[2,105],132:[2,105],133:[2,105],134:[2,105],135:[2,105],136:[2,105]},{6:[2,55],25:[2,55],27:109,28:[1,73],44:110,48:106,49:[2,55],54:[2,55],55:107,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{5:115,25:[1,5]},{8:116,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:118,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:119,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{13:121,14:122,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,58:47,59:48,61:120,63:25,64:26,65:27,75:[1,70],82:[1,28],87:[1,58],88:[1,59],89:[1,57],100:[1,56]},{13:121,14:122,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,58:47,59:48,61:124,63:25,64:26,65:27,75:[1,70],82:[1,28],87:[1,58],88:[1,59],89:[1,57],100:[1,56]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],40:[2,72],49:[2,72],54:[2,72],57:[2,72],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,72],73:[2,72],77:[2,72],79:[1,128],83:[2,72],84:[2,72],85:[2,72],90:[2,72],92:[2,72],101:[2,72],103:[2,72],104:[2,72],105:[2,72],109:[2,72],117:[2,72],125:[2,72],127:[2,72],128:[2,72],129:[1,125],130:[1,126],131:[2,72],132:[2,72],133:[2,72],134:[2,72],135:[2,72],136:[2,72],137:[1,127]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],49:[2,180],54:[2,180],57:[2,180],72:[2,180],77:[2,180],85:[2,180],90:[2,180],92:[2,180],101:[2,180],103:[2,180],104:[2,180],105:[2,180],109:[2,180],117:[2,180],120:[1,129],125:[2,180],127:[2,180],128:[2,180],131:[2,180],132:[2,180],133:[2,180],134:[2,180],135:[2,180],136:[2,180]},{5:130,25:[1,5]},{5:131,25:[1,5]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],49:[2,147],54:[2,147],57:[2,147],72:[2,147],77:[2,147],85:[2,147],90:[2,147],92:[2,147],101:[2,147],103:[2,147],104:[2,147],105:[2,147],109:[2,147],117:[2,147],125:[2,147],127:[2,147],128:[2,147],131:[2,147],132:[2,147],133:[2,147],134:[2,147],135:[2,147],136:[2,147]},{5:132,25:[1,5]},{8:133,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,134],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,95],5:135,6:[2,95],13:121,14:122,25:[1,5],26:[2,95],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:123,44:63,49:[2,95],54:[2,95],57:[2,95],58:47,59:48,61:137,63:25,64:26,65:27,72:[2,95],75:[1,70],77:[2,95],79:[1,136],82:[1,28],85:[2,95],87:[1,58],88:[1,59],89:[1,57],90:[2,95],92:[2,95],100:[1,56],101:[2,95],103:[2,95],104:[2,95],105:[2,95],109:[2,95],117:[2,95],125:[2,95],127:[2,95],128:[2,95],131:[2,95],132:[2,95],133:[2,95],134:[2,95],135:[2,95],136:[2,95]},{8:138,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,47],6:[2,47],8:139,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,47],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],101:[2,47],102:39,103:[2,47],105:[2,47],106:40,107:[1,67],108:41,109:[2,47],110:69,118:[1,42],123:37,124:[1,64],125:[2,47],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],54:[2,48],77:[2,48],101:[2,48],103:[2,48],105:[2,48],109:[2,48],125:[2,48]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],40:[2,73],49:[2,73],54:[2,73],57:[2,73],66:[2,73],67:[2,73],68:[2,73],70:[2,73],72:[2,73],73:[2,73],77:[2,73],83:[2,73],84:[2,73],85:[2,73],90:[2,73],92:[2,73],101:[2,73],103:[2,73],104:[2,73],105:[2,73],109:[2,73],117:[2,73],125:[2,73],127:[2,73],128:[2,73],131:[2,73],132:[2,73],133:[2,73],134:[2,73],135:[2,73],136:[2,73]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],40:[2,74],49:[2,74],54:[2,74],57:[2,74],66:[2,74],67:[2,74],68:[2,74],70:[2,74],72:[2,74],73:[2,74],77:[2,74],83:[2,74],84:[2,74],85:[2,74],90:[2,74],92:[2,74],101:[2,74],103:[2,74],104:[2,74],105:[2,74],109:[2,74],117:[2,74],125:[2,74],127:[2,74],128:[2,74],131:[2,74],132:[2,74],133:[2,74],134:[2,74],135:[2,74],136:[2,74]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],49:[2,29],54:[2,29],57:[2,29],66:[2,29],67:[2,29],68:[2,29],70:[2,29],72:[2,29],73:[2,29],77:[2,29],83:[2,29],84:[2,29],85:[2,29],90:[2,29],92:[2,29],101:[2,29],103:[2,29],104:[2,29],105:[2,29],109:[2,29],117:[2,29],125:[2,29],127:[2,29],128:[2,29],131:[2,29],132:[2,29],133:[2,29],134:[2,29],135:[2,29],136:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],49:[2,30],54:[2,30],57:[2,30],66:[2,30],67:[2,30],68:[2,30],70:[2,30],72:[2,30],73:[2,30],77:[2,30],83:[2,30],84:[2,30],85:[2,30],90:[2,30],92:[2,30],101:[2,30],103:[2,30],104:[2,30],105:[2,30],109:[2,30],117:[2,30],125:[2,30],127:[2,30],128:[2,30],131:[2,30],132:[2,30],133:[2,30],134:[2,30],135:[2,30],136:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],49:[2,31],54:[2,31],57:[2,31],66:[2,31],67:[2,31],68:[2,31],70:[2,31],72:[2,31],73:[2,31],77:[2,31],83:[2,31],84:[2,31],85:[2,31],90:[2,31],92:[2,31],101:[2,31],103:[2,31],104:[2,31],105:[2,31],109:[2,31],117:[2,31],125:[2,31],127:[2,31],128:[2,31],131:[2,31],132:[2,31],133:[2,31],134:[2,31],135:[2,31],136:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],49:[2,32],54:[2,32],57:[2,32],66:[2,32],67:[2,32],68:[2,32],70:[2,32],72:[2,32],73:[2,32],77:[2,32],83:[2,32],84:[2,32],85:[2,32],90:[2,32],92:[2,32],101:[2,32],103:[2,32],104:[2,32],105:[2,32],109:[2,32],117:[2,32],125:[2,32],127:[2,32],128:[2,32],131:[2,32],132:[2,32],133:[2,32],134:[2,32],135:[2,32],136:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],49:[2,33],54:[2,33],57:[2,33],66:[2,33],67:[2,33],68:[2,33],70:[2,33],72:[2,33],73:[2,33],77:[2,33],83:[2,33],84:[2,33],85:[2,33],90:[2,33],92:[2,33],101:[2,33],103:[2,33],104:[2,33],105:[2,33],109:[2,33],117:[2,33],125:[2,33],127:[2,33],128:[2,33],131:[2,33],132:[2,33],133:[2,33],134:[2,33],135:[2,33],136:[2,33]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],49:[2,34],54:[2,34],57:[2,34],66:[2,34],67:[2,34],68:[2,34],70:[2,34],72:[2,34],73:[2,34],77:[2,34],83:[2,34],84:[2,34],85:[2,34],90:[2,34],92:[2,34],101:[2,34],103:[2,34],104:[2,34],105:[2,34],109:[2,34],117:[2,34],125:[2,34],127:[2,34],128:[2,34],131:[2,34],132:[2,34],133:[2,34],134:[2,34],135:[2,34],136:[2,34]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],49:[2,35],54:[2,35],57:[2,35],66:[2,35],67:[2,35],68:[2,35],70:[2,35],72:[2,35],73:[2,35],77:[2,35],83:[2,35],84:[2,35],85:[2,35],90:[2,35],92:[2,35],101:[2,35],103:[2,35],104:[2,35],105:[2,35],109:[2,35],117:[2,35],125:[2,35],127:[2,35],128:[2,35],131:[2,35],132:[2,35],133:[2,35],134:[2,35],135:[2,35],136:[2,35]},{4:140,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,141],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:142,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:144,87:[1,58],88:[1,59],89:[1,57],90:[1,143],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],49:[2,111],54:[2,111],57:[2,111],66:[2,111],67:[2,111],68:[2,111],70:[2,111],72:[2,111],73:[2,111],77:[2,111],83:[2,111],84:[2,111],85:[2,111],90:[2,111],92:[2,111],101:[2,111],103:[2,111],104:[2,111],105:[2,111],109:[2,111],117:[2,111],125:[2,111],127:[2,111],128:[2,111],131:[2,111],132:[2,111],133:[2,111],134:[2,111],135:[2,111],136:[2,111]},{1:[2,112],6:[2,112],25:[2,112],26:[2,112],27:148,28:[1,73],49:[2,112],54:[2,112],57:[2,112],66:[2,112],67:[2,112],68:[2,112],70:[2,112],72:[2,112],73:[2,112],77:[2,112],83:[2,112],84:[2,112],85:[2,112],90:[2,112],92:[2,112],101:[2,112],103:[2,112],104:[2,112],105:[2,112],109:[2,112],117:[2,112],125:[2,112],127:[2,112],128:[2,112],131:[2,112],132:[2,112],133:[2,112],134:[2,112],135:[2,112],136:[2,112]},{25:[2,51]},{25:[2,52]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],40:[2,68],49:[2,68],54:[2,68],57:[2,68],66:[2,68],67:[2,68],68:[2,68],70:[2,68],72:[2,68],73:[2,68],77:[2,68],79:[2,68],83:[2,68],84:[2,68],85:[2,68],90:[2,68],92:[2,68],101:[2,68],103:[2,68],104:[2,68],105:[2,68],109:[2,68],117:[2,68],125:[2,68],127:[2,68],128:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[2,68],136:[2,68],137:[2,68]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],40:[2,71],49:[2,71],54:[2,71],57:[2,71],66:[2,71],67:[2,71],68:[2,71],70:[2,71],72:[2,71],73:[2,71],77:[2,71],79:[2,71],83:[2,71],84:[2,71],85:[2,71],90:[2,71],92:[2,71],101:[2,71],103:[2,71],104:[2,71],105:[2,71],109:[2,71],117:[2,71],125:[2,71],127:[2,71],128:[2,71],129:[2,71],130:[2,71],131:[2,71],132:[2,71],133:[2,71],134:[2,71],135:[2,71],136:[2,71],137:[2,71]},{8:149,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:150,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:151,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{5:152,8:153,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,5],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{27:158,28:[1,73],44:159,58:160,59:161,64:154,75:[1,70],88:[1,113],89:[1,57],112:155,113:[1,156],114:157},{111:162,115:[1,163],116:[1,164]},{6:[2,90],11:168,25:[2,90],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:166,42:167,44:171,46:[1,46],54:[2,90],76:165,77:[2,90],88:[1,113]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],43:[2,27],49:[2,27],54:[2,27],57:[2,27],66:[2,27],67:[2,27],68:[2,27],70:[2,27],72:[2,27],73:[2,27],77:[2,27],83:[2,27],84:[2,27],85:[2,27],90:[2,27],92:[2,27],101:[2,27],103:[2,27],104:[2,27],105:[2,27],109:[2,27],117:[2,27],125:[2,27],127:[2,27],128:[2,27],131:[2,27],132:[2,27],133:[2,27],134:[2,27],135:[2,27],136:[2,27]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],43:[2,28],49:[2,28],54:[2,28],57:[2,28],66:[2,28],67:[2,28],68:[2,28],70:[2,28],72:[2,28],73:[2,28],77:[2,28],83:[2,28],84:[2,28],85:[2,28],90:[2,28],92:[2,28],101:[2,28],103:[2,28],104:[2,28],105:[2,28],109:[2,28],117:[2,28],125:[2,28],127:[2,28],128:[2,28],131:[2,28],132:[2,28],133:[2,28],134:[2,28],135:[2,28],136:[2,28]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],40:[2,26],43:[2,26],49:[2,26],54:[2,26],57:[2,26],66:[2,26],67:[2,26],68:[2,26],70:[2,26],72:[2,26],73:[2,26],77:[2,26],79:[2,26],83:[2,26],84:[2,26],85:[2,26],90:[2,26],92:[2,26],101:[2,26],103:[2,26],104:[2,26],105:[2,26],109:[2,26],115:[2,26],116:[2,26],117:[2,26],125:[2,26],127:[2,26],128:[2,26],129:[2,26],130:[2,26],131:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26],136:[2,26],137:[2,26]},{1:[2,6],6:[2,6],7:172,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,26:[2,6],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],101:[2,6],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,3]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],49:[2,24],54:[2,24],57:[2,24],72:[2,24],77:[2,24],85:[2,24],90:[2,24],92:[2,24],97:[2,24],98:[2,24],101:[2,24],103:[2,24],104:[2,24],105:[2,24],109:[2,24],117:[2,24],120:[2,24],122:[2,24],125:[2,24],127:[2,24],128:[2,24],131:[2,24],132:[2,24],133:[2,24],134:[2,24],135:[2,24],136:[2,24]},{6:[1,74],26:[1,173]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],49:[2,191],54:[2,191],57:[2,191],72:[2,191],77:[2,191],85:[2,191],90:[2,191],92:[2,191],101:[2,191],103:[2,191],104:[2,191],105:[2,191],109:[2,191],117:[2,191],125:[2,191],127:[2,191],128:[2,191],131:[2,191],132:[2,191],133:[2,191],134:[2,191],135:[2,191],136:[2,191]},{8:174,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:175,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:176,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:177,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:178,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:179,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:180,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:181,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],49:[2,146],54:[2,146],57:[2,146],72:[2,146],77:[2,146],85:[2,146],90:[2,146],92:[2,146],101:[2,146],103:[2,146],104:[2,146],105:[2,146],109:[2,146],117:[2,146],125:[2,146],127:[2,146],128:[2,146],131:[2,146],132:[2,146],133:[2,146],134:[2,146],135:[2,146],136:[2,146]},{1:[2,151],6:[2,151],25:[2,151],26:[2,151],49:[2,151],54:[2,151],57:[2,151],72:[2,151],77:[2,151],85:[2,151],90:[2,151],92:[2,151],101:[2,151],103:[2,151],104:[2,151],105:[2,151],109:[2,151],117:[2,151],125:[2,151],127:[2,151],128:[2,151],131:[2,151],132:[2,151],133:[2,151],134:[2,151],135:[2,151],136:[2,151]},{8:182,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],49:[2,145],54:[2,145],57:[2,145],72:[2,145],77:[2,145],85:[2,145],90:[2,145],92:[2,145],101:[2,145],103:[2,145],104:[2,145],105:[2,145],109:[2,145],117:[2,145],125:[2,145],127:[2,145],128:[2,145],131:[2,145],132:[2,145],133:[2,145],134:[2,145],135:[2,145],136:[2,145]},{1:[2,150],6:[2,150],25:[2,150],26:[2,150],49:[2,150],54:[2,150],57:[2,150],72:[2,150],77:[2,150],85:[2,150],90:[2,150],92:[2,150],101:[2,150],103:[2,150],104:[2,150],105:[2,150],109:[2,150],117:[2,150],125:[2,150],127:[2,150],128:[2,150],131:[2,150],132:[2,150],133:[2,150],134:[2,150],135:[2,150],136:[2,150]},{81:183,84:[1,105]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],40:[2,69],49:[2,69],54:[2,69],57:[2,69],66:[2,69],67:[2,69],68:[2,69],70:[2,69],72:[2,69],73:[2,69],77:[2,69],79:[2,69],83:[2,69],84:[2,69],85:[2,69],90:[2,69],92:[2,69],101:[2,69],103:[2,69],104:[2,69],105:[2,69],109:[2,69],117:[2,69],125:[2,69],127:[2,69],128:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69],135:[2,69],136:[2,69],137:[2,69]},{84:[2,108]},{27:184,28:[1,73]},{27:185,28:[1,73]},{1:[2,83],6:[2,83],25:[2,83],26:[2,83],27:186,28:[1,73],40:[2,83],49:[2,83],54:[2,83],57:[2,83],66:[2,83],67:[2,83],68:[2,83],70:[2,83],72:[2,83],73:[2,83],77:[2,83],79:[2,83],83:[2,83],84:[2,83],85:[2,83],90:[2,83],92:[2,83],101:[2,83],103:[2,83],104:[2,83],105:[2,83],109:[2,83],117:[2,83],125:[2,83],127:[2,83],128:[2,83],129:[2,83],130:[2,83],131:[2,83],132:[2,83],133:[2,83],134:[2,83],135:[2,83],136:[2,83],137:[2,83]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],40:[2,84],49:[2,84],54:[2,84],57:[2,84],66:[2,84],67:[2,84],68:[2,84],70:[2,84],72:[2,84],73:[2,84],77:[2,84],79:[2,84],83:[2,84],84:[2,84],85:[2,84],90:[2,84],92:[2,84],101:[2,84],103:[2,84],104:[2,84],105:[2,84],109:[2,84],117:[2,84],125:[2,84],127:[2,84],128:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84],135:[2,84],136:[2,84],137:[2,84]},{8:188,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],57:[1,192],58:47,59:48,61:36,63:25,64:26,65:27,71:187,74:189,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],91:190,92:[1,191],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{69:193,70:[1,99],73:[1,100]},{81:194,84:[1,105]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],40:[2,70],49:[2,70],54:[2,70],57:[2,70],66:[2,70],67:[2,70],68:[2,70],70:[2,70],72:[2,70],73:[2,70],77:[2,70],79:[2,70],83:[2,70],84:[2,70],85:[2,70],90:[2,70],92:[2,70],101:[2,70],103:[2,70],104:[2,70],105:[2,70],109:[2,70],117:[2,70],125:[2,70],127:[2,70],128:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70],135:[2,70],136:[2,70],137:[2,70]},{6:[1,196],8:195,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,197],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],49:[2,106],54:[2,106],57:[2,106],66:[2,106],67:[2,106],68:[2,106],70:[2,106],72:[2,106],73:[2,106],77:[2,106],83:[2,106],84:[2,106],85:[2,106],90:[2,106],92:[2,106],101:[2,106],103:[2,106],104:[2,106],105:[2,106],109:[2,106],117:[2,106],125:[2,106],127:[2,106],128:[2,106],131:[2,106],132:[2,106],133:[2,106],134:[2,106],135:[2,106],136:[2,106]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],85:[1,198],86:199,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],49:[1,201],53:203,54:[1,202]},{6:[2,56],25:[2,56],26:[2,56],49:[2,56],54:[2,56]},{6:[2,60],25:[2,60],26:[2,60],40:[1,205],49:[2,60],54:[2,60],57:[1,204]},{6:[2,63],25:[2,63],26:[2,63],40:[2,63],49:[2,63],54:[2,63],57:[2,63]},{6:[2,64],25:[2,64],26:[2,64],40:[2,64],49:[2,64],54:[2,64],57:[2,64]},{6:[2,65],25:[2,65],26:[2,65],40:[2,65],49:[2,65],54:[2,65],57:[2,65]},{6:[2,66],25:[2,66],26:[2,66],40:[2,66],49:[2,66],54:[2,66],57:[2,66]},{27:148,28:[1,73]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:144,87:[1,58],88:[1,59],89:[1,57],90:[1,143],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,50],6:[2,50],25:[2,50],26:[2,50],49:[2,50],54:[2,50],57:[2,50],72:[2,50],77:[2,50],85:[2,50],90:[2,50],92:[2,50],101:[2,50],103:[2,50],104:[2,50],105:[2,50],109:[2,50],117:[2,50],125:[2,50],127:[2,50],128:[2,50],131:[2,50],132:[2,50],133:[2,50],134:[2,50],135:[2,50],136:[2,50]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],49:[2,184],54:[2,184],57:[2,184],72:[2,184],77:[2,184],85:[2,184],90:[2,184],92:[2,184],101:[2,184],102:87,103:[2,184],104:[2,184],105:[2,184],108:88,109:[2,184],110:69,117:[2,184],125:[2,184],127:[2,184],128:[2,184],131:[1,78],132:[2,184],133:[2,184],134:[2,184],135:[2,184],136:[2,184]},{102:90,103:[1,65],105:[1,66],108:91,109:[1,68],110:69,125:[1,89]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],49:[2,185],54:[2,185],57:[2,185],72:[2,185],77:[2,185],85:[2,185],90:[2,185],92:[2,185],101:[2,185],102:87,103:[2,185],104:[2,185],105:[2,185],108:88,109:[2,185],110:69,117:[2,185],125:[2,185],127:[2,185],128:[2,185],131:[1,78],132:[2,185],133:[2,185],134:[2,185],135:[2,185],136:[2,185]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],49:[2,186],54:[2,186],57:[2,186],72:[2,186],77:[2,186],85:[2,186],90:[2,186],92:[2,186],101:[2,186],102:87,103:[2,186],104:[2,186],105:[2,186],108:88,109:[2,186],110:69,117:[2,186],125:[2,186],127:[2,186],128:[2,186],131:[1,78],132:[2,186],133:[2,186],134:[2,186],135:[2,186],136:[2,186]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],49:[2,187],54:[2,187],57:[2,187],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,187],73:[2,72],77:[2,187],83:[2,72],84:[2,72],85:[2,187],90:[2,187],92:[2,187],101:[2,187],103:[2,187],104:[2,187],105:[2,187],109:[2,187],117:[2,187],125:[2,187],127:[2,187],128:[2,187],131:[2,187],132:[2,187],133:[2,187],134:[2,187],135:[2,187],136:[2,187]},{62:93,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],73:[1,100],80:92,83:[1,94],84:[2,107]},{62:102,66:[1,95],67:[1,96],68:[1,97],69:98,70:[1,99],73:[1,100],80:101,83:[1,94],84:[2,107]},{66:[2,75],67:[2,75],68:[2,75],70:[2,75],73:[2,75],83:[2,75],84:[2,75]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],49:[2,188],54:[2,188],57:[2,188],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,188],73:[2,72],77:[2,188],83:[2,72],84:[2,72],85:[2,188],90:[2,188],92:[2,188],101:[2,188],103:[2,188],104:[2,188],105:[2,188],109:[2,188],117:[2,188],125:[2,188],127:[2,188],128:[2,188],131:[2,188],132:[2,188],133:[2,188],134:[2,188],135:[2,188],136:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],49:[2,189],54:[2,189],57:[2,189],72:[2,189],77:[2,189],85:[2,189],90:[2,189],92:[2,189],101:[2,189],103:[2,189],104:[2,189],105:[2,189],109:[2,189],117:[2,189],125:[2,189],127:[2,189],128:[2,189],131:[2,189],132:[2,189],133:[2,189],134:[2,189],135:[2,189],136:[2,189]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],49:[2,190],54:[2,190],57:[2,190],72:[2,190],77:[2,190],85:[2,190],90:[2,190],92:[2,190],101:[2,190],103:[2,190],104:[2,190],105:[2,190],109:[2,190],117:[2,190],125:[2,190],127:[2,190],128:[2,190],131:[2,190],132:[2,190],133:[2,190],134:[2,190],135:[2,190],136:[2,190]},{8:206,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,207],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:208,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{5:209,25:[1,5],124:[1,210]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],49:[2,132],54:[2,132],57:[2,132],72:[2,132],77:[2,132],85:[2,132],90:[2,132],92:[2,132],96:211,97:[1,212],98:[1,213],101:[2,132],103:[2,132],104:[2,132],105:[2,132],109:[2,132],117:[2,132],125:[2,132],127:[2,132],128:[2,132],131:[2,132],132:[2,132],133:[2,132],134:[2,132],135:[2,132],136:[2,132]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],49:[2,144],54:[2,144],57:[2,144],72:[2,144],77:[2,144],85:[2,144],90:[2,144],92:[2,144],101:[2,144],103:[2,144],104:[2,144],105:[2,144],109:[2,144],117:[2,144],125:[2,144],127:[2,144],128:[2,144],131:[2,144],132:[2,144],133:[2,144],134:[2,144],135:[2,144],136:[2,144]},{1:[2,152],6:[2,152],25:[2,152],26:[2,152],49:[2,152],54:[2,152],57:[2,152],72:[2,152],77:[2,152],85:[2,152],90:[2,152],92:[2,152],101:[2,152],103:[2,152],104:[2,152],105:[2,152],109:[2,152],117:[2,152],125:[2,152],127:[2,152],128:[2,152],131:[2,152],132:[2,152],133:[2,152],134:[2,152],135:[2,152],136:[2,152]},{25:[1,214],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{119:215,121:216,122:[1,217]},{1:[2,96],6:[2,96],25:[2,96],26:[2,96],49:[2,96],54:[2,96],57:[2,96],72:[2,96],77:[2,96],85:[2,96],90:[2,96],92:[2,96],101:[2,96],103:[2,96],104:[2,96],105:[2,96],109:[2,96],117:[2,96],125:[2,96],127:[2,96],128:[2,96],131:[2,96],132:[2,96],133:[2,96],134:[2,96],135:[2,96],136:[2,96]},{8:218,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,99],5:219,6:[2,99],25:[1,5],26:[2,99],49:[2,99],54:[2,99],57:[2,99],66:[2,72],67:[2,72],68:[2,72],70:[2,72],72:[2,99],73:[2,72],77:[2,99],79:[1,220],83:[2,72],84:[2,72],85:[2,99],90:[2,99],92:[2,99],101:[2,99],103:[2,99],104:[2,99],105:[2,99],109:[2,99],117:[2,99],125:[2,99],127:[2,99],128:[2,99],131:[2,99],132:[2,99],133:[2,99],134:[2,99],135:[2,99],136:[2,99]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],49:[2,137],54:[2,137],57:[2,137],72:[2,137],77:[2,137],85:[2,137],90:[2,137],92:[2,137],101:[2,137],102:87,103:[2,137],104:[2,137],105:[2,137],108:88,109:[2,137],110:69,117:[2,137],125:[2,137],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,46],6:[2,46],26:[2,46],101:[2,46],102:87,103:[2,46],105:[2,46],108:88,109:[2,46],110:69,125:[2,46],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,74],101:[1,221]},{4:222,7:4,8:6,9:7,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,128],25:[2,128],54:[2,128],57:[1,224],90:[2,128],91:223,92:[1,191],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],40:[2,114],49:[2,114],54:[2,114],57:[2,114],66:[2,114],67:[2,114],68:[2,114],70:[2,114],72:[2,114],73:[2,114],77:[2,114],83:[2,114],84:[2,114],85:[2,114],90:[2,114],92:[2,114],101:[2,114],103:[2,114],104:[2,114],105:[2,114],109:[2,114],115:[2,114],116:[2,114],117:[2,114],125:[2,114],127:[2,114],128:[2,114],131:[2,114],132:[2,114],133:[2,114],134:[2,114],135:[2,114],136:[2,114]},{6:[2,53],25:[2,53],53:225,54:[1,226],90:[2,53]},{6:[2,123],25:[2,123],26:[2,123],54:[2,123],85:[2,123],90:[2,123]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:227,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,129],25:[2,129],26:[2,129],54:[2,129],85:[2,129],90:[2,129]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],40:[2,113],43:[2,113],49:[2,113],54:[2,113],57:[2,113],66:[2,113],67:[2,113],68:[2,113],70:[2,113],72:[2,113],73:[2,113],77:[2,113],79:[2,113],83:[2,113],84:[2,113],85:[2,113],90:[2,113],92:[2,113],101:[2,113],103:[2,113],104:[2,113],105:[2,113],109:[2,113],115:[2,113],116:[2,113],117:[2,113],125:[2,113],127:[2,113],128:[2,113],129:[2,113],130:[2,113],131:[2,113],132:[2,113],133:[2,113],134:[2,113],135:[2,113],136:[2,113],137:[2,113]},{5:228,25:[1,5],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],49:[2,140],54:[2,140],57:[2,140],72:[2,140],77:[2,140],85:[2,140],90:[2,140],92:[2,140],101:[2,140],102:87,103:[1,65],104:[1,229],105:[1,66],108:88,109:[1,68],110:69,117:[2,140],125:[2,140],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],49:[2,142],54:[2,142],57:[2,142],72:[2,142],77:[2,142],85:[2,142],90:[2,142],92:[2,142],101:[2,142],102:87,103:[1,65],104:[1,230],105:[1,66],108:88,109:[1,68],110:69,117:[2,142],125:[2,142],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],49:[2,148],54:[2,148],57:[2,148],72:[2,148],77:[2,148],85:[2,148],90:[2,148],92:[2,148],101:[2,148],103:[2,148],104:[2,148],105:[2,148],109:[2,148],117:[2,148],125:[2,148],127:[2,148],128:[2,148],131:[2,148],132:[2,148],133:[2,148],134:[2,148],135:[2,148],136:[2,148]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],49:[2,149],54:[2,149],57:[2,149],72:[2,149],77:[2,149],85:[2,149],90:[2,149],92:[2,149],101:[2,149],102:87,103:[1,65],104:[2,149],105:[1,66],108:88,109:[1,68],110:69,117:[2,149],125:[2,149],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,153],6:[2,153],25:[2,153],26:[2,153],49:[2,153],54:[2,153],57:[2,153],72:[2,153],77:[2,153],85:[2,153],90:[2,153],92:[2,153],101:[2,153],103:[2,153],104:[2,153],105:[2,153],109:[2,153],117:[2,153],125:[2,153],127:[2,153],128:[2,153],131:[2,153],132:[2,153],133:[2,153],134:[2,153],135:[2,153],136:[2,153]},{115:[2,155],116:[2,155]},{27:158,28:[1,73],44:159,58:160,59:161,75:[1,70],88:[1,113],89:[1,114],112:231,114:157},{54:[1,232],115:[2,161],116:[2,161]},{54:[2,157],115:[2,157],116:[2,157]},{54:[2,158],115:[2,158],116:[2,158]},{54:[2,159],115:[2,159],116:[2,159]},{54:[2,160],115:[2,160],116:[2,160]},{1:[2,154],6:[2,154],25:[2,154],26:[2,154],49:[2,154],54:[2,154],57:[2,154],72:[2,154],77:[2,154],85:[2,154],90:[2,154],92:[2,154],101:[2,154],103:[2,154],104:[2,154],105:[2,154],109:[2,154],117:[2,154],125:[2,154],127:[2,154],128:[2,154],131:[2,154],132:[2,154],133:[2,154],134:[2,154],135:[2,154],136:[2,154]},{8:233,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:234,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],53:235,54:[1,236],77:[2,53]},{6:[2,91],25:[2,91],26:[2,91],54:[2,91],77:[2,91]},{6:[2,39],25:[2,39],26:[2,39],43:[1,237],54:[2,39],77:[2,39]},{6:[2,42],25:[2,42],26:[2,42],54:[2,42],77:[2,42]},{6:[2,43],25:[2,43],26:[2,43],43:[2,43],54:[2,43],77:[2,43]},{6:[2,44],25:[2,44],26:[2,44],43:[2,44],54:[2,44],77:[2,44]},{6:[2,45],25:[2,45],26:[2,45],43:[2,45],54:[2,45],77:[2,45]},{1:[2,5],6:[2,5],26:[2,5],101:[2,5]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],49:[2,25],54:[2,25],57:[2,25],72:[2,25],77:[2,25],85:[2,25],90:[2,25],92:[2,25],97:[2,25],98:[2,25],101:[2,25],103:[2,25],104:[2,25],105:[2,25],109:[2,25],117:[2,25],120:[2,25],122:[2,25],125:[2,25],127:[2,25],128:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25],135:[2,25],136:[2,25]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],49:[2,192],54:[2,192],57:[2,192],72:[2,192],77:[2,192],85:[2,192],90:[2,192],92:[2,192],101:[2,192],102:87,103:[2,192],104:[2,192],105:[2,192],108:88,109:[2,192],110:69,117:[2,192],125:[2,192],127:[2,192],128:[2,192],131:[1,78],132:[1,81],133:[2,192],134:[2,192],135:[2,192],136:[2,192]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],49:[2,193],54:[2,193],57:[2,193],72:[2,193],77:[2,193],85:[2,193],90:[2,193],92:[2,193],101:[2,193],102:87,103:[2,193],104:[2,193],105:[2,193],108:88,109:[2,193],110:69,117:[2,193],125:[2,193],127:[2,193],128:[2,193],131:[1,78],132:[1,81],133:[2,193],134:[2,193],135:[2,193],136:[2,193]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],49:[2,194],54:[2,194],57:[2,194],72:[2,194],77:[2,194],85:[2,194],90:[2,194],92:[2,194],101:[2,194],102:87,103:[2,194],104:[2,194],105:[2,194],108:88,109:[2,194],110:69,117:[2,194],125:[2,194],127:[2,194],128:[2,194],131:[1,78],132:[2,194],133:[2,194],134:[2,194],135:[2,194],136:[2,194]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],49:[2,195],54:[2,195],57:[2,195],72:[2,195],77:[2,195],85:[2,195],90:[2,195],92:[2,195],101:[2,195],102:87,103:[2,195],104:[2,195],105:[2,195],108:88,109:[2,195],110:69,117:[2,195],125:[2,195],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[2,195],134:[2,195],135:[2,195],136:[2,195]},{1:[2,196],6:[2,196],25:[2,196],26:[2,196],49:[2,196],54:[2,196],57:[2,196],72:[2,196],77:[2,196],85:[2,196],90:[2,196],92:[2,196],101:[2,196],102:87,103:[2,196],104:[2,196],105:[2,196],108:88,109:[2,196],110:69,117:[2,196],125:[2,196],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[2,196],135:[2,196],136:[1,85]},{1:[2,197],6:[2,197],25:[2,197],26:[2,197],49:[2,197],54:[2,197],57:[2,197],72:[2,197],77:[2,197],85:[2,197],90:[2,197],92:[2,197],101:[2,197],102:87,103:[2,197],104:[2,197],105:[2,197],108:88,109:[2,197],110:69,117:[2,197],125:[2,197],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[2,197],136:[1,85]},{1:[2,198],6:[2,198],25:[2,198],26:[2,198],49:[2,198],54:[2,198],57:[2,198],72:[2,198],77:[2,198],85:[2,198],90:[2,198],92:[2,198],101:[2,198],102:87,103:[2,198],104:[2,198],105:[2,198],108:88,109:[2,198],110:69,117:[2,198],125:[2,198],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[2,198],135:[2,198],136:[2,198]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],49:[2,183],54:[2,183],57:[2,183],72:[2,183],77:[2,183],85:[2,183],90:[2,183],92:[2,183],101:[2,183],102:87,103:[1,65],104:[2,183],105:[1,66],108:88,109:[1,68],110:69,117:[2,183],125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],49:[2,182],54:[2,182],57:[2,182],72:[2,182],77:[2,182],85:[2,182],90:[2,182],92:[2,182],101:[2,182],102:87,103:[1,65],104:[2,182],105:[1,66],108:88,109:[1,68],110:69,117:[2,182],125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,103],6:[2,103],25:[2,103],26:[2,103],49:[2,103],54:[2,103],57:[2,103],66:[2,103],67:[2,103],68:[2,103],70:[2,103],72:[2,103],73:[2,103],77:[2,103],83:[2,103],84:[2,103],85:[2,103],90:[2,103],92:[2,103],101:[2,103],103:[2,103],104:[2,103],105:[2,103],109:[2,103],117:[2,103],125:[2,103],127:[2,103],128:[2,103],131:[2,103],132:[2,103],133:[2,103],134:[2,103],135:[2,103],136:[2,103]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],40:[2,80],49:[2,80],54:[2,80],57:[2,80],66:[2,80],67:[2,80],68:[2,80],70:[2,80],72:[2,80],73:[2,80],77:[2,80],79:[2,80],83:[2,80],84:[2,80],85:[2,80],90:[2,80],92:[2,80],101:[2,80],103:[2,80],104:[2,80],105:[2,80],109:[2,80],117:[2,80],125:[2,80],127:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80],136:[2,80],137:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],40:[2,81],49:[2,81],54:[2,81],57:[2,81],66:[2,81],67:[2,81],68:[2,81],70:[2,81],72:[2,81],73:[2,81],77:[2,81],79:[2,81],83:[2,81],84:[2,81],85:[2,81],90:[2,81],92:[2,81],101:[2,81],103:[2,81],104:[2,81],105:[2,81],109:[2,81],117:[2,81],125:[2,81],127:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81],136:[2,81],137:[2,81]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],40:[2,82],49:[2,82],54:[2,82],57:[2,82],66:[2,82],67:[2,82],68:[2,82],70:[2,82],72:[2,82],73:[2,82],77:[2,82],79:[2,82],83:[2,82],84:[2,82],85:[2,82],90:[2,82],92:[2,82],101:[2,82],103:[2,82],104:[2,82],105:[2,82],109:[2,82],117:[2,82],125:[2,82],127:[2,82],128:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82],136:[2,82],137:[2,82]},{72:[1,238]},{57:[1,192],72:[2,87],91:239,92:[1,191],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{72:[2,88]},{8:240,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,72:[2,122],75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{12:[2,116],28:[2,116],30:[2,116],31:[2,116],33:[2,116],34:[2,116],35:[2,116],36:[2,116],37:[2,116],38:[2,116],45:[2,116],46:[2,116],47:[2,116],51:[2,116],52:[2,116],72:[2,116],75:[2,116],78:[2,116],82:[2,116],87:[2,116],88:[2,116],89:[2,116],95:[2,116],99:[2,116],100:[2,116],103:[2,116],105:[2,116],107:[2,116],109:[2,116],118:[2,116],124:[2,116],126:[2,116],127:[2,116],128:[2,116],129:[2,116],130:[2,116]},{12:[2,117],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],72:[2,117],75:[2,117],78:[2,117],82:[2,117],87:[2,117],88:[2,117],89:[2,117],95:[2,117],99:[2,117],100:[2,117],103:[2,117],105:[2,117],107:[2,117],109:[2,117],118:[2,117],124:[2,117],126:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117]},{1:[2,86],6:[2,86],25:[2,86],26:[2,86],40:[2,86],49:[2,86],54:[2,86],57:[2,86],66:[2,86],67:[2,86],68:[2,86],70:[2,86],72:[2,86],73:[2,86],77:[2,86],79:[2,86],83:[2,86],84:[2,86],85:[2,86],90:[2,86],92:[2,86],101:[2,86],103:[2,86],104:[2,86],105:[2,86],109:[2,86],117:[2,86],125:[2,86],127:[2,86],128:[2,86],129:[2,86],130:[2,86],131:[2,86],132:[2,86],133:[2,86],134:[2,86],135:[2,86],136:[2,86],137:[2,86]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],49:[2,104],54:[2,104],57:[2,104],66:[2,104],67:[2,104],68:[2,104],70:[2,104],72:[2,104],73:[2,104],77:[2,104],83:[2,104],84:[2,104],85:[2,104],90:[2,104],92:[2,104],101:[2,104],103:[2,104],104:[2,104],105:[2,104],109:[2,104],117:[2,104],125:[2,104],127:[2,104],128:[2,104],131:[2,104],132:[2,104],133:[2,104],134:[2,104],135:[2,104],136:[2,104]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],49:[2,36],54:[2,36],57:[2,36],72:[2,36],77:[2,36],85:[2,36],90:[2,36],92:[2,36],101:[2,36],102:87,103:[2,36],104:[2,36],105:[2,36],108:88,109:[2,36],110:69,117:[2,36],125:[2,36],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:241,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:242,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],49:[2,109],54:[2,109],57:[2,109],66:[2,109],67:[2,109],68:[2,109],70:[2,109],72:[2,109],73:[2,109],77:[2,109],83:[2,109],84:[2,109],85:[2,109],90:[2,109],92:[2,109],101:[2,109],103:[2,109],104:[2,109],105:[2,109],109:[2,109],117:[2,109],125:[2,109],127:[2,109],128:[2,109],131:[2,109],132:[2,109],133:[2,109],134:[2,109],135:[2,109],136:[2,109]},{6:[2,53],25:[2,53],53:243,54:[1,226],85:[2,53]},{6:[2,128],25:[2,128],26:[2,128],54:[2,128],57:[1,244],85:[2,128],90:[2,128],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{50:245,51:[1,60],52:[1,61]},{6:[2,54],25:[2,54],26:[2,54],27:109,28:[1,73],44:110,55:246,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[1,247],25:[1,248]},{6:[2,61],25:[2,61],26:[2,61],49:[2,61],54:[2,61]},{8:249,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,199],6:[2,199],25:[2,199],26:[2,199],49:[2,199],54:[2,199],57:[2,199],72:[2,199],77:[2,199],85:[2,199],90:[2,199],92:[2,199],101:[2,199],102:87,103:[2,199],104:[2,199],105:[2,199],108:88,109:[2,199],110:69,117:[2,199],125:[2,199],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:250,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,201],6:[2,201],25:[2,201],26:[2,201],49:[2,201],54:[2,201],57:[2,201],72:[2,201],77:[2,201],85:[2,201],90:[2,201],92:[2,201],101:[2,201],102:87,103:[2,201],104:[2,201],105:[2,201],108:88,109:[2,201],110:69,117:[2,201],125:[2,201],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],49:[2,181],54:[2,181],57:[2,181],72:[2,181],77:[2,181],85:[2,181],90:[2,181],92:[2,181],101:[2,181],103:[2,181],104:[2,181],105:[2,181],109:[2,181],117:[2,181],125:[2,181],127:[2,181],128:[2,181],131:[2,181],132:[2,181],133:[2,181],134:[2,181],135:[2,181],136:[2,181]},{8:251,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],49:[2,133],54:[2,133],57:[2,133],72:[2,133],77:[2,133],85:[2,133],90:[2,133],92:[2,133],97:[1,252],101:[2,133],103:[2,133],104:[2,133],105:[2,133],109:[2,133],117:[2,133],125:[2,133],127:[2,133],128:[2,133],131:[2,133],132:[2,133],133:[2,133],134:[2,133],135:[2,133],136:[2,133]},{5:253,25:[1,5]},{27:254,28:[1,73]},{119:255,121:216,122:[1,217]},{26:[1,256],120:[1,257],121:258,122:[1,217]},{26:[2,174],120:[2,174],122:[2,174]},{8:260,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],94:259,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,97],5:261,6:[2,97],25:[1,5],26:[2,97],49:[2,97],54:[2,97],57:[2,97],72:[2,97],77:[2,97],85:[2,97],90:[2,97],92:[2,97],101:[2,97],102:87,103:[1,65],104:[2,97],105:[1,66],108:88,109:[1,68],110:69,117:[2,97],125:[2,97],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],49:[2,100],54:[2,100],57:[2,100],72:[2,100],77:[2,100],85:[2,100],90:[2,100],92:[2,100],101:[2,100],103:[2,100],104:[2,100],105:[2,100],109:[2,100],117:[2,100],125:[2,100],127:[2,100],128:[2,100],131:[2,100],132:[2,100],133:[2,100],134:[2,100],135:[2,100],136:[2,100]},{8:262,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],49:[2,138],54:[2,138],57:[2,138],66:[2,138],67:[2,138],68:[2,138],70:[2,138],72:[2,138],73:[2,138],77:[2,138],83:[2,138],84:[2,138],85:[2,138],90:[2,138],92:[2,138],101:[2,138],103:[2,138],104:[2,138],105:[2,138],109:[2,138],117:[2,138],125:[2,138],127:[2,138],128:[2,138],131:[2,138],132:[2,138],133:[2,138],134:[2,138],135:[2,138],136:[2,138]},{6:[1,74],26:[1,263]},{8:264,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,67],12:[2,117],25:[2,67],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],54:[2,67],75:[2,117],78:[2,117],82:[2,117],87:[2,117],88:[2,117],89:[2,117],90:[2,67],95:[2,117],99:[2,117],100:[2,117],103:[2,117],105:[2,117],107:[2,117],109:[2,117],118:[2,117],124:[2,117],126:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117]},{6:[1,266],25:[1,267],90:[1,265]},{6:[2,54],8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[2,54],26:[2,54],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],85:[2,54],87:[1,58],88:[1,59],89:[1,57],90:[2,54],93:268,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,53],25:[2,53],26:[2,53],53:269,54:[1,226]},{1:[2,178],6:[2,178],25:[2,178],26:[2,178],49:[2,178],54:[2,178],57:[2,178],72:[2,178],77:[2,178],85:[2,178],90:[2,178],92:[2,178],101:[2,178],103:[2,178],104:[2,178],105:[2,178],109:[2,178],117:[2,178],120:[2,178],125:[2,178],127:[2,178],128:[2,178],131:[2,178],132:[2,178],133:[2,178],134:[2,178],135:[2,178],136:[2,178]},{8:270,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:271,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{115:[2,156],116:[2,156]},{27:158,28:[1,73],44:159,58:160,59:161,75:[1,70],88:[1,113],89:[1,114],114:272},{1:[2,163],6:[2,163],25:[2,163],26:[2,163],49:[2,163],54:[2,163],57:[2,163],72:[2,163],77:[2,163],85:[2,163],90:[2,163],92:[2,163],101:[2,163],102:87,103:[2,163],104:[1,273],105:[2,163],108:88,109:[2,163],110:69,117:[1,274],125:[2,163],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,164],6:[2,164],25:[2,164],26:[2,164],49:[2,164],54:[2,164],57:[2,164],72:[2,164],77:[2,164],85:[2,164],90:[2,164],92:[2,164],101:[2,164],102:87,103:[2,164],104:[1,275],105:[2,164],108:88,109:[2,164],110:69,117:[2,164],125:[2,164],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,277],25:[1,278],77:[1,276]},{6:[2,54],11:168,25:[2,54],26:[2,54],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:279,42:167,44:171,46:[1,46],77:[2,54],88:[1,113]},{8:280,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,281],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],40:[2,85],49:[2,85],54:[2,85],57:[2,85],66:[2,85],67:[2,85],68:[2,85],70:[2,85],72:[2,85],73:[2,85],77:[2,85],79:[2,85],83:[2,85],84:[2,85],85:[2,85],90:[2,85],92:[2,85],101:[2,85],103:[2,85],104:[2,85],105:[2,85],109:[2,85],117:[2,85],125:[2,85],127:[2,85],128:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85],135:[2,85],136:[2,85],137:[2,85]},{8:282,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,72:[2,120],75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{72:[2,121],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,37],6:[2,37],25:[2,37],26:[2,37],49:[2,37],54:[2,37],57:[2,37],72:[2,37],77:[2,37],85:[2,37],90:[2,37],92:[2,37],101:[2,37],102:87,103:[2,37],104:[2,37],105:[2,37],108:88,109:[2,37],110:69,117:[2,37],125:[2,37],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{26:[1,283],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,266],25:[1,267],85:[1,284]},{6:[2,67],25:[2,67],26:[2,67],54:[2,67],85:[2,67],90:[2,67]},{5:285,25:[1,5]},{6:[2,57],25:[2,57],26:[2,57],49:[2,57],54:[2,57]},{27:109,28:[1,73],44:110,55:286,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[2,55],25:[2,55],26:[2,55],27:109,28:[1,73],44:110,48:287,54:[2,55],55:107,56:108,58:111,59:112,75:[1,70],88:[1,113],89:[1,114]},{6:[2,62],25:[2,62],26:[2,62],49:[2,62],54:[2,62],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{26:[1,288],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{5:289,25:[1,5],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{5:290,25:[1,5]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],49:[2,134],54:[2,134],57:[2,134],72:[2,134],77:[2,134],85:[2,134],90:[2,134],92:[2,134],101:[2,134],103:[2,134],104:[2,134],105:[2,134],109:[2,134],117:[2,134],125:[2,134],127:[2,134],128:[2,134],131:[2,134],132:[2,134],133:[2,134],134:[2,134],135:[2,134],136:[2,134]},{5:291,25:[1,5]},{26:[1,292],120:[1,293],121:258,122:[1,217]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],49:[2,172],54:[2,172],57:[2,172],72:[2,172],77:[2,172],85:[2,172],90:[2,172],92:[2,172],101:[2,172],103:[2,172],104:[2,172],105:[2,172],109:[2,172],117:[2,172],125:[2,172],127:[2,172],128:[2,172],131:[2,172],132:[2,172],133:[2,172],134:[2,172],135:[2,172],136:[2,172]},{5:294,25:[1,5]},{26:[2,175],120:[2,175],122:[2,175]},{5:295,25:[1,5],54:[1,296]},{25:[2,130],54:[2,130],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],49:[2,98],54:[2,98],57:[2,98],72:[2,98],77:[2,98],85:[2,98],90:[2,98],92:[2,98],101:[2,98],103:[2,98],104:[2,98],105:[2,98],109:[2,98],117:[2,98],125:[2,98],127:[2,98],128:[2,98],131:[2,98],132:[2,98],133:[2,98],134:[2,98],135:[2,98],136:[2,98]},{1:[2,101],5:297,6:[2,101],25:[1,5],26:[2,101],49:[2,101],54:[2,101],57:[2,101],72:[2,101],77:[2,101],85:[2,101],90:[2,101],92:[2,101],101:[2,101],102:87,103:[1,65],104:[2,101],105:[1,66],108:88,109:[1,68],110:69,117:[2,101],125:[2,101],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{101:[1,298]},{90:[1,299],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,115],6:[2,115],25:[2,115],26:[2,115],40:[2,115],49:[2,115],54:[2,115],57:[2,115],66:[2,115],67:[2,115],68:[2,115],70:[2,115],72:[2,115],73:[2,115],77:[2,115],83:[2,115],84:[2,115],85:[2,115],90:[2,115],92:[2,115],101:[2,115],103:[2,115],104:[2,115],105:[2,115],109:[2,115],115:[2,115],116:[2,115],117:[2,115],125:[2,115],127:[2,115],128:[2,115],131:[2,115],132:[2,115],133:[2,115],134:[2,115],135:[2,115],136:[2,115]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],93:300,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:200,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,25:[1,146],27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,60:147,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],86:301,87:[1,58],88:[1,59],89:[1,57],93:145,95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[2,124],25:[2,124],26:[2,124],54:[2,124],85:[2,124],90:[2,124]},{6:[1,266],25:[1,267],26:[1,302]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],49:[2,141],54:[2,141],57:[2,141],72:[2,141],77:[2,141],85:[2,141],90:[2,141],92:[2,141],101:[2,141],102:87,103:[1,65],104:[2,141],105:[1,66],108:88,109:[1,68],110:69,117:[2,141],125:[2,141],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],49:[2,143],54:[2,143],57:[2,143],72:[2,143],77:[2,143],85:[2,143],90:[2,143],92:[2,143],101:[2,143],102:87,103:[1,65],104:[2,143],105:[1,66],108:88,109:[1,68],110:69,117:[2,143],125:[2,143],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{115:[2,162],116:[2,162]},{8:303,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:304,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:305,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,89],6:[2,89],25:[2,89],26:[2,89],40:[2,89],49:[2,89],54:[2,89],57:[2,89],66:[2,89],67:[2,89],68:[2,89],70:[2,89],72:[2,89],73:[2,89],77:[2,89],83:[2,89],84:[2,89],85:[2,89],90:[2,89],92:[2,89],101:[2,89],103:[2,89],104:[2,89],105:[2,89],109:[2,89],115:[2,89],116:[2,89],117:[2,89],125:[2,89],127:[2,89],128:[2,89],131:[2,89],132:[2,89],133:[2,89],134:[2,89],135:[2,89],136:[2,89]},{11:168,27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:306,42:167,44:171,46:[1,46],88:[1,113]},{6:[2,90],11:168,25:[2,90],26:[2,90],27:169,28:[1,73],29:170,30:[1,71],31:[1,72],41:166,42:167,44:171,46:[1,46],54:[2,90],76:307,88:[1,113]},{6:[2,92],25:[2,92],26:[2,92],54:[2,92],77:[2,92]},{6:[2,40],25:[2,40],26:[2,40],54:[2,40],77:[2,40],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{8:308,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{72:[2,119],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,38],6:[2,38],25:[2,38],26:[2,38],49:[2,38],54:[2,38],57:[2,38],72:[2,38],77:[2,38],85:[2,38],90:[2,38],92:[2,38],101:[2,38],103:[2,38],104:[2,38],105:[2,38],109:[2,38],117:[2,38],125:[2,38],127:[2,38],128:[2,38],131:[2,38],132:[2,38],133:[2,38],134:[2,38],135:[2,38],136:[2,38]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],49:[2,110],54:[2,110],57:[2,110],66:[2,110],67:[2,110],68:[2,110],70:[2,110],72:[2,110],73:[2,110],77:[2,110],83:[2,110],84:[2,110],85:[2,110],90:[2,110],92:[2,110],101:[2,110],103:[2,110],104:[2,110],105:[2,110],109:[2,110],117:[2,110],125:[2,110],127:[2,110],128:[2,110],131:[2,110],132:[2,110],133:[2,110],134:[2,110],135:[2,110],136:[2,110]},{1:[2,49],6:[2,49],25:[2,49],26:[2,49],49:[2,49],54:[2,49],57:[2,49],72:[2,49],77:[2,49],85:[2,49],90:[2,49],92:[2,49],101:[2,49],103:[2,49],104:[2,49],105:[2,49],109:[2,49],117:[2,49],125:[2,49],127:[2,49],128:[2,49],131:[2,49],132:[2,49],133:[2,49],134:[2,49],135:[2,49],136:[2,49]},{6:[2,58],25:[2,58],26:[2,58],49:[2,58],54:[2,58]},{6:[2,53],25:[2,53],26:[2,53],53:309,54:[1,202]},{1:[2,200],6:[2,200],25:[2,200],26:[2,200],49:[2,200],54:[2,200],57:[2,200],72:[2,200],77:[2,200],85:[2,200],90:[2,200],92:[2,200],101:[2,200],103:[2,200],104:[2,200],105:[2,200],109:[2,200],117:[2,200],125:[2,200],127:[2,200],128:[2,200],131:[2,200],132:[2,200],133:[2,200],134:[2,200],135:[2,200],136:[2,200]},{1:[2,179],6:[2,179],25:[2,179],26:[2,179],49:[2,179],54:[2,179],57:[2,179],72:[2,179],77:[2,179],85:[2,179],90:[2,179],92:[2,179],101:[2,179],103:[2,179],104:[2,179],105:[2,179],109:[2,179],117:[2,179],120:[2,179],125:[2,179],127:[2,179],128:[2,179],131:[2,179],132:[2,179],133:[2,179],134:[2,179],135:[2,179],136:[2,179]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],49:[2,135],54:[2,135],57:[2,135],72:[2,135],77:[2,135],85:[2,135],90:[2,135],92:[2,135],101:[2,135],103:[2,135],104:[2,135],105:[2,135],109:[2,135],117:[2,135],125:[2,135],127:[2,135],128:[2,135],131:[2,135],132:[2,135],133:[2,135],134:[2,135],135:[2,135],136:[2,135]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],49:[2,136],54:[2,136],57:[2,136],72:[2,136],77:[2,136],85:[2,136],90:[2,136],92:[2,136],97:[2,136],101:[2,136],103:[2,136],104:[2,136],105:[2,136],109:[2,136],117:[2,136],125:[2,136],127:[2,136],128:[2,136],131:[2,136],132:[2,136],133:[2,136],134:[2,136],135:[2,136],136:[2,136]},{1:[2,170],6:[2,170],25:[2,170],26:[2,170],49:[2,170],54:[2,170],57:[2,170],72:[2,170],77:[2,170],85:[2,170],90:[2,170],92:[2,170],101:[2,170],103:[2,170],104:[2,170],105:[2,170],109:[2,170],117:[2,170],125:[2,170],127:[2,170],128:[2,170],131:[2,170],132:[2,170],133:[2,170],134:[2,170],135:[2,170],136:[2,170]},{5:310,25:[1,5]},{26:[1,311]},{6:[1,312],26:[2,176],120:[2,176],122:[2,176]},{8:313,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{1:[2,102],6:[2,102],25:[2,102],26:[2,102],49:[2,102],54:[2,102],57:[2,102],72:[2,102],77:[2,102],85:[2,102],90:[2,102],92:[2,102],101:[2,102],103:[2,102],104:[2,102],105:[2,102],109:[2,102],117:[2,102],125:[2,102],127:[2,102],128:[2,102],131:[2,102],132:[2,102],133:[2,102],134:[2,102],135:[2,102],136:[2,102]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],49:[2,139],54:[2,139],57:[2,139],66:[2,139],67:[2,139],68:[2,139],70:[2,139],72:[2,139],73:[2,139],77:[2,139],83:[2,139],84:[2,139],85:[2,139],90:[2,139],92:[2,139],101:[2,139],103:[2,139],104:[2,139],105:[2,139],109:[2,139],117:[2,139],125:[2,139],127:[2,139],128:[2,139],131:[2,139],132:[2,139],133:[2,139],134:[2,139],135:[2,139],136:[2,139]},{1:[2,118],6:[2,118],25:[2,118],26:[2,118],49:[2,118],54:[2,118],57:[2,118],66:[2,118],67:[2,118],68:[2,118],70:[2,118],72:[2,118],73:[2,118],77:[2,118],83:[2,118],84:[2,118],85:[2,118],90:[2,118],92:[2,118],101:[2,118],103:[2,118],104:[2,118],105:[2,118],109:[2,118],117:[2,118],125:[2,118],127:[2,118],128:[2,118],131:[2,118],132:[2,118],133:[2,118],134:[2,118],135:[2,118],136:[2,118]},{6:[2,125],25:[2,125],26:[2,125],54:[2,125],85:[2,125],90:[2,125]},{6:[2,53],25:[2,53],26:[2,53],53:314,54:[1,226]},{6:[2,126],25:[2,126],26:[2,126],54:[2,126],85:[2,126],90:[2,126]},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],49:[2,165],54:[2,165],57:[2,165],72:[2,165],77:[2,165],85:[2,165],90:[2,165],92:[2,165],101:[2,165],102:87,103:[2,165],104:[2,165],105:[2,165],108:88,109:[2,165],110:69,117:[1,315],125:[2,165],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],49:[2,167],54:[2,167],57:[2,167],72:[2,167],77:[2,167],85:[2,167],90:[2,167],92:[2,167],101:[2,167],102:87,103:[2,167],104:[1,316],105:[2,167],108:88,109:[2,167],110:69,117:[2,167],125:[2,167],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],49:[2,166],54:[2,166],57:[2,166],72:[2,166],77:[2,166],85:[2,166],90:[2,166],92:[2,166],101:[2,166],102:87,103:[2,166],104:[2,166],105:[2,166],108:88,109:[2,166],110:69,117:[2,166],125:[2,166],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[2,93],25:[2,93],26:[2,93],54:[2,93],77:[2,93]},{6:[2,53],25:[2,53],26:[2,53],53:317,54:[1,236]},{26:[1,318],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,247],25:[1,248],26:[1,319]},{26:[1,320]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],49:[2,173],54:[2,173],57:[2,173],72:[2,173],77:[2,173],85:[2,173],90:[2,173],92:[2,173],101:[2,173],103:[2,173],104:[2,173],105:[2,173],109:[2,173],117:[2,173],125:[2,173],127:[2,173],128:[2,173],131:[2,173],132:[2,173],133:[2,173],134:[2,173],135:[2,173],136:[2,173]},{26:[2,177],120:[2,177],122:[2,177]},{25:[2,131],54:[2,131],102:87,103:[1,65],105:[1,66],108:88,109:[1,68],110:69,125:[1,86],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[1,266],25:[1,267],26:[1,321]},{8:322,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{8:323,9:117,10:20,11:21,12:[1,22],13:8,14:9,15:10,16:11,17:12,18:13,19:14,20:15,21:16,22:17,23:18,24:19,27:62,28:[1,73],29:49,30:[1,71],31:[1,72],32:24,33:[1,50],34:[1,51],35:[1,52],36:[1,53],37:[1,54],38:[1,55],39:23,44:63,45:[1,45],46:[1,46],47:[1,29],50:30,51:[1,60],52:[1,61],58:47,59:48,61:36,63:25,64:26,65:27,75:[1,70],78:[1,43],82:[1,28],87:[1,58],88:[1,59],89:[1,57],95:[1,38],99:[1,44],100:[1,56],102:39,103:[1,65],105:[1,66],106:40,107:[1,67],108:41,109:[1,68],110:69,118:[1,42],123:37,124:[1,64],126:[1,31],127:[1,32],128:[1,33],129:[1,34],130:[1,35]},{6:[1,277],25:[1,278],26:[1,324]},{6:[2,41],25:[2,41],26:[2,41],54:[2,41],77:[2,41]},{6:[2,59],25:[2,59],26:[2,59],49:[2,59],54:[2,59]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],49:[2,171],54:[2,171],57:[2,171],72:[2,171],77:[2,171],85:[2,171],90:[2,171],92:[2,171],101:[2,171],103:[2,171],104:[2,171],105:[2,171],109:[2,171],117:[2,171],125:[2,171],127:[2,171],128:[2,171],131:[2,171],132:[2,171],133:[2,171],134:[2,171],135:[2,171],136:[2,171]},{6:[2,127],25:[2,127],26:[2,127],54:[2,127],85:[2,127],90:[2,127]},{1:[2,168],6:[2,168],25:[2,168],26:[2,168],49:[2,168],54:[2,168],57:[2,168],72:[2,168],77:[2,168],85:[2,168],90:[2,168],92:[2,168],101:[2,168],102:87,103:[2,168],104:[2,168],105:[2,168],108:88,109:[2,168],110:69,117:[2,168],125:[2,168],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{1:[2,169],6:[2,169],25:[2,169],26:[2,169],49:[2,169],54:[2,169],57:[2,169],72:[2,169],77:[2,169],85:[2,169],90:[2,169],92:[2,169],101:[2,169],102:87,103:[2,169],104:[2,169],105:[2,169],108:88,109:[2,169],110:69,117:[2,169],125:[2,169],127:[1,80],128:[1,79],131:[1,78],132:[1,81],133:[1,82],134:[1,83],135:[1,84],136:[1,85]},{6:[2,94],25:[2,94],26:[2,94],54:[2,94],77:[2,94]}], -defaultActions: {60:[2,51],61:[2,52],75:[2,3],94:[2,108],189:[2,88]}, -parseError: function parseError(str, hash) { - throw new Error(str); -}, -parse: function parse(input) { - var self = this, - stack = [0], - vstack = [null], // semantic value stack - lstack = [], // location stack - table = this.table, - yytext = '', - yylineno = 0, - yyleng = 0, - recovering = 0, - TERROR = 2, - EOF = 1; - - //this.reductionCount = this.shiftCount = 0; - - this.lexer.setInput(input); - this.lexer.yy = this.yy; - this.yy.lexer = this.lexer; - if (typeof this.lexer.yylloc == 'undefined') - this.lexer.yylloc = {}; - var yyloc = this.lexer.yylloc; - lstack.push(yyloc); - - if (typeof this.yy.parseError === 'function') - this.parseError = this.yy.parseError; - - function popStack (n) { - stack.length = stack.length - 2*n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - - function lex() { - var token; - token = self.lexer.lex() || 1; // $end = 1 - // if token isn't its numeric value, convert - if (typeof token !== 'number') { - token = self.symbols_[token] || token; - } - return token; - } - - var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected; - while (true) { - // retreive state number from top of stack - state = stack[stack.length-1]; - - // use default actions if available - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol == null) - symbol = lex(); - // read action for current state and first input - action = table[state] && table[state][symbol]; - } - - // handle parse error - _handle_error: - if (typeof action === 'undefined' || !action.length || !action[0]) { - - if (!recovering) { - // Report error - expected = []; - for (p in table[state]) if (this.terminals_[p] && p > 2) { - expected.push("'"+this.terminals_[p]+"'"); - } - var errStr = ''; - if (this.lexer.showPosition) { - errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'"; - } else { - errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " + - (symbol == 1 /*EOF*/ ? "end of input" : - ("'"+(this.terminals_[symbol] || symbol)+"'")); - } - this.parseError(errStr, - {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); - } - - // just recovered from another error - if (recovering == 3) { - if (symbol == EOF) { - throw new Error(errStr || 'Parsing halted.'); - } - - // discard current lookahead and grab another - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - symbol = lex(); - } - - // try to recover from error - while (1) { - // check for error recovery rule in this state - if ((TERROR.toString()) in table[state]) { - break; - } - if (state == 0) { - throw new Error(errStr || 'Parsing halted.'); - } - popStack(1); - state = stack[stack.length-1]; - } - - preErrorSymbol = symbol; // save the lookahead token - symbol = TERROR; // insert generic error symbol as new lookahead - state = stack[stack.length-1]; - action = table[state] && table[state][TERROR]; - recovering = 3; // allow 3 real symbols to be shifted before reporting a new error - } - - // this shouldn't happen, unless resolve defaults are off - if (action[0] instanceof Array && action.length > 1) { - throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol); - } - - switch (action[0]) { - - case 1: // shift - //this.shiftCount++; - - stack.push(symbol); - vstack.push(this.lexer.yytext); - lstack.push(this.lexer.yylloc); - stack.push(action[1]); // push state - symbol = null; - if (!preErrorSymbol) { // normal execution/no error - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - if (recovering > 0) - recovering--; - } else { // error just occurred, resume old lookahead f/ before error - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - - case 2: // reduce - //this.reductionCount++; - - len = this.productions_[action[1]][1]; - - // perform semantic action - yyval.$ = vstack[vstack.length-len]; // default to $$ = $1 - // default location, uses first token for firsts, last for lasts - yyval._$ = { - first_line: lstack[lstack.length-(len||1)].first_line, - last_line: lstack[lstack.length-1].last_line, - first_column: lstack[lstack.length-(len||1)].first_column, - last_column: lstack[lstack.length-1].last_column - }; - r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); - - if (typeof r !== 'undefined') { - return r; - } - - // pop off stack - if (len) { - stack = stack.slice(0,-1*len*2); - vstack = vstack.slice(0, -1*len); - lstack = lstack.slice(0, -1*len); - } - - stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce) - vstack.push(yyval.$); - lstack.push(yyval._$); - // goto new state = table[STATE][NONTERMINAL] - newState = table[stack[stack.length-2]][stack[stack.length-1]]; - stack.push(newState); - break; - - case 3: // accept - return true; - } - - } - - return true; -}}; -undefined -return parser; -})(); -if (typeof require !== 'undefined' && typeof exports !== 'undefined') { -exports.parser = parser; -exports.parse = function () { return parser.parse.apply(parser, arguments); } -exports.main = function commonjsMain(args) { - if (!args[1]) - throw new Error('Usage: '+args[0]+' FILE'); - if (typeof process !== 'undefined') { - var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8"); - } else { - var cwd = require("file").path(require("file").cwd()); - var source = cwd.join(args[1]).read({charset: "utf-8"}); - } - return exports.parser.parse(source); -} -if (typeof module !== 'undefined' && require.main === module) { - exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); -} -} \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js deleted file mode 100644 index b4a4765d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/repl.js +++ /dev/null @@ -1,261 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var ACCESSOR, CoffeeScript, Module, REPL_PROMPT, REPL_PROMPT_CONTINUATION, REPL_PROMPT_MULTILINE, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, inspect, multilineMode, pipedInput, readline, repl, run, stdin, stdout; - - stdin = process.openStdin(); - - stdout = process.stdout; - - CoffeeScript = require('./coffee-script'); - - readline = require('readline'); - - inspect = require('util').inspect; - - Script = require('vm').Script; - - Module = require('module'); - - REPL_PROMPT = 'coffee> '; - - REPL_PROMPT_MULTILINE = '------> '; - - REPL_PROMPT_CONTINUATION = '......> '; - - enableColours = false; - - if (process.platform !== 'win32') { - enableColours = !process.env.NODE_DISABLE_COLORS; - } - - error = function(err) { - return stdout.write((err.stack || err.toString()) + '\n'); - }; - - ACCESSOR = /\s*([\w\.]+)(?:\.(\w*))$/; - - SIMPLEVAR = /(\w+)$/i; - - autocomplete = function(text) { - return completeAttribute(text) || completeVariable(text) || [[], text]; - }; - - completeAttribute = function(text) { - var all, completions, key, match, obj, possibilities, prefix, val; - if (match = text.match(ACCESSOR)) { - all = match[0], obj = match[1], prefix = match[2]; - try { - val = Script.runInThisContext(obj); - } catch (error) { - return; - } - val = Object(val); - possibilities = Object.getOwnPropertyNames(val); - for (key in val) { - if (~possibilities.indexOf(val)) { - possibilities.push(key); - } - } - completions = getCompletions(prefix, possibilities); - return [completions, prefix]; - } - }; - - completeVariable = function(text) { - var completions, free, keywords, possibilities, r, vars, _ref; - free = (_ref = text.match(SIMPLEVAR)) != null ? _ref[1] : void 0; - if (text === "") { - free = ""; - } - if (free != null) { - vars = Script.runInThisContext('Object.getOwnPropertyNames(Object(this))'); - keywords = (function() { - var _i, _len, _ref1, _results; - _ref1 = CoffeeScript.RESERVED; - _results = []; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - r = _ref1[_i]; - if (r.slice(0, 2) !== '__') { - _results.push(r); - } - } - return _results; - })(); - possibilities = vars.concat(keywords); - completions = getCompletions(free, possibilities); - return [completions, free]; - } - }; - - getCompletions = function(prefix, candidates) { - var el, _i, _len, _results; - _results = []; - for (_i = 0, _len = candidates.length; _i < _len; _i++) { - el = candidates[_i]; - if (el.indexOf(prefix) === 0) { - _results.push(el); - } - } - return _results; - }; - - process.on('uncaughtException', error); - - backlog = ''; - - run = function(buffer) { - var code, returnValue, _; - buffer = buffer.replace(/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/, "$1$2$3"); - buffer = buffer.replace(/[\r\n]+$/, ""); - if (multilineMode) { - backlog += "" + buffer + "\n"; - repl.setPrompt(REPL_PROMPT_CONTINUATION); - repl.prompt(); - return; - } - if (!buffer.toString().trim() && !backlog) { - repl.prompt(); - return; - } - code = backlog += buffer; - if (code[code.length - 1] === '\\') { - backlog = "" + backlog.slice(0, -1) + "\n"; - repl.setPrompt(REPL_PROMPT_CONTINUATION); - repl.prompt(); - return; - } - repl.setPrompt(REPL_PROMPT); - backlog = ''; - try { - _ = global._; - returnValue = CoffeeScript["eval"]("_=(" + code + "\n)", { - filename: 'repl', - modulename: 'repl' - }); - if (returnValue === void 0) { - global._ = _; - } - repl.output.write("" + (inspect(returnValue, false, 2, enableColours)) + "\n"); - } catch (err) { - error(err); - } - return repl.prompt(); - }; - - if (stdin.readable) { - pipedInput = ''; - repl = { - prompt: function() { - return stdout.write(this._prompt); - }, - setPrompt: function(p) { - return this._prompt = p; - }, - input: stdin, - output: stdout, - on: function() {} - }; - stdin.on('data', function(chunk) { - var line, lines, _i, _len, _ref; - pipedInput += chunk; - if (!/\n/.test(pipedInput)) { - return; - } - lines = pipedInput.split("\n"); - pipedInput = lines[lines.length - 1]; - _ref = lines.slice(0, -1); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - line = _ref[_i]; - if (!(line)) { - continue; - } - stdout.write("" + line + "\n"); - run(line); - } - }); - stdin.on('end', function() { - var line, _i, _len, _ref; - _ref = pipedInput.trim().split("\n"); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - line = _ref[_i]; - if (!(line)) { - continue; - } - stdout.write("" + line + "\n"); - run(line); - } - stdout.write('\n'); - return process.exit(0); - }); - } else { - if (readline.createInterface.length < 3) { - repl = readline.createInterface(stdin, autocomplete); - stdin.on('data', function(buffer) { - return repl.write(buffer); - }); - } else { - repl = readline.createInterface(stdin, stdout, autocomplete); - } - } - - multilineMode = false; - - repl.input.on('keypress', function(char, key) { - var cursorPos, newPrompt; - if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'v')) { - return; - } - cursorPos = repl.cursor; - repl.output.cursorTo(0); - repl.output.clearLine(1); - multilineMode = !multilineMode; - if (!multilineMode && backlog) { - repl._line(); - } - backlog = ''; - repl.setPrompt((newPrompt = multilineMode ? REPL_PROMPT_MULTILINE : REPL_PROMPT)); - repl.prompt(); - return repl.output.cursorTo(newPrompt.length + (repl.cursor = cursorPos)); - }); - - repl.input.on('keypress', function(char, key) { - if (!(multilineMode && repl.line)) { - return; - } - if (!(key && key.ctrl && !key.meta && !key.shift && key.name === 'd')) { - return; - } - multilineMode = false; - return repl._line(); - }); - - repl.on('attemptClose', function() { - if (multilineMode) { - multilineMode = false; - repl.output.cursorTo(0); - repl.output.clearLine(1); - repl._onLine(repl.line); - return; - } - if (backlog) { - backlog = ''; - repl.output.write('\n'); - repl.setPrompt(REPL_PROMPT); - return repl.prompt(); - } else { - return repl.close(); - } - }); - - repl.on('close', function() { - repl.output.write('\n'); - return repl.input.destroy(); - }); - - repl.on('line', run); - - repl.setPrompt(REPL_PROMPT); - - repl.prompt(); - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js deleted file mode 100644 index d26133ca..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/rewriter.js +++ /dev/null @@ -1,349 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice; - - exports.Rewriter = (function() { - - function Rewriter() {} - - Rewriter.prototype.rewrite = function(tokens) { - this.tokens = tokens; - this.removeLeadingNewlines(); - this.removeMidExpressionNewlines(); - this.closeOpenCalls(); - this.closeOpenIndexes(); - this.addImplicitIndentation(); - this.tagPostfixConditionals(); - this.addImplicitBraces(); - this.addImplicitParentheses(); - return this.tokens; - }; - - Rewriter.prototype.scanTokens = function(block) { - var i, token, tokens; - tokens = this.tokens; - i = 0; - while (token = tokens[i]) { - i += block.call(this, token, i, tokens); - } - return true; - }; - - Rewriter.prototype.detectEnd = function(i, condition, action) { - var levels, token, tokens, _ref, _ref1; - tokens = this.tokens; - levels = 0; - while (token = tokens[i]) { - if (levels === 0 && condition.call(this, token, i)) { - return action.call(this, token, i); - } - if (!token || levels < 0) { - return action.call(this, token, i - 1); - } - if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) { - levels += 1; - } else if (_ref1 = token[0], __indexOf.call(EXPRESSION_END, _ref1) >= 0) { - levels -= 1; - } - i += 1; - } - return i - 1; - }; - - Rewriter.prototype.removeLeadingNewlines = function() { - var i, tag, _i, _len, _ref; - _ref = this.tokens; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - tag = _ref[i][0]; - if (tag !== 'TERMINATOR') { - break; - } - } - if (i) { - return this.tokens.splice(0, i); - } - }; - - Rewriter.prototype.removeMidExpressionNewlines = function() { - return this.scanTokens(function(token, i, tokens) { - var _ref; - if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) { - return 1; - } - tokens.splice(i, 1); - return 0; - }); - }; - - Rewriter.prototype.closeOpenCalls = function() { - var action, condition; - condition = function(token, i) { - var _ref; - return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')'; - }; - action = function(token, i) { - return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END'; - }; - return this.scanTokens(function(token, i) { - if (token[0] === 'CALL_START') { - this.detectEnd(i + 1, condition, action); - } - return 1; - }); - }; - - Rewriter.prototype.closeOpenIndexes = function() { - var action, condition; - condition = function(token, i) { - var _ref; - return (_ref = token[0]) === ']' || _ref === 'INDEX_END'; - }; - action = function(token, i) { - return token[0] = 'INDEX_END'; - }; - return this.scanTokens(function(token, i) { - if (token[0] === 'INDEX_START') { - this.detectEnd(i + 1, condition, action); - } - return 1; - }); - }; - - Rewriter.prototype.addImplicitBraces = function() { - var action, condition, sameLine, stack, start, startIndent, startIndex, startsLine; - stack = []; - start = null; - startsLine = null; - sameLine = true; - startIndent = 0; - startIndex = 0; - condition = function(token, i) { - var one, tag, three, two, _ref, _ref1; - _ref = this.tokens.slice(i + 1, (i + 3) + 1 || 9e9), one = _ref[0], two = _ref[1], three = _ref[2]; - if ('HERECOMMENT' === (one != null ? one[0] : void 0)) { - return false; - } - tag = token[0]; - if (__indexOf.call(LINEBREAKS, tag) >= 0) { - sameLine = false; - } - return (((tag === 'TERMINATOR' || tag === 'OUTDENT') || (__indexOf.call(IMPLICIT_END, tag) >= 0 && sameLine && !(i - startIndex === 1))) && ((!startsLine && this.tag(i - 1) !== ',') || !((two != null ? two[0] : void 0) === ':' || (one != null ? one[0] : void 0) === '@' && (three != null ? three[0] : void 0) === ':'))) || (tag === ',' && one && ((_ref1 = one[0]) !== 'IDENTIFIER' && _ref1 !== 'NUMBER' && _ref1 !== 'STRING' && _ref1 !== '@' && _ref1 !== 'TERMINATOR' && _ref1 !== 'OUTDENT')); - }; - action = function(token, i) { - var tok; - tok = this.generate('}', '}', token[2]); - return this.tokens.splice(i, 0, tok); - }; - return this.scanTokens(function(token, i, tokens) { - var ago, idx, prevTag, tag, tok, value, _ref, _ref1; - if (_ref = (tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0) { - stack.push([(tag === 'INDENT' && this.tag(i - 1) === '{' ? '{' : tag), i]); - return 1; - } - if (__indexOf.call(EXPRESSION_END, tag) >= 0) { - start = stack.pop(); - return 1; - } - if (!(tag === ':' && ((ago = this.tag(i - 2)) === ':' || ((_ref1 = stack[stack.length - 1]) != null ? _ref1[0] : void 0) !== '{'))) { - return 1; - } - sameLine = true; - startIndex = i + 1; - stack.push(['{']); - idx = ago === '@' ? i - 2 : i - 1; - while (this.tag(idx - 2) === 'HERECOMMENT') { - idx -= 2; - } - prevTag = this.tag(idx - 1); - startsLine = !prevTag || (__indexOf.call(LINEBREAKS, prevTag) >= 0); - value = new String('{'); - value.generated = true; - tok = this.generate('{', value, token[2]); - tokens.splice(idx, 0, tok); - this.detectEnd(i + 2, condition, action); - return 2; - }); - }; - - Rewriter.prototype.addImplicitParentheses = function() { - var action, condition, noCall, seenControl, seenSingle; - noCall = seenSingle = seenControl = false; - condition = function(token, i) { - var post, tag, _ref, _ref1; - tag = token[0]; - if (!seenSingle && token.fromThen) { - return true; - } - if (tag === 'IF' || tag === 'ELSE' || tag === 'CATCH' || tag === '->' || tag === '=>' || tag === 'CLASS') { - seenSingle = true; - } - if (tag === 'IF' || tag === 'ELSE' || tag === 'SWITCH' || tag === 'TRY' || tag === '=') { - seenControl = true; - } - if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') { - return true; - } - return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref1 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{'))); - }; - action = function(token, i) { - return this.tokens.splice(i, 0, this.generate('CALL_END', ')', token[2])); - }; - return this.scanTokens(function(token, i, tokens) { - var callObject, current, next, prev, tag, _ref, _ref1, _ref2; - tag = token[0]; - if (tag === 'CLASS' || tag === 'IF' || tag === 'FOR' || tag === 'WHILE') { - noCall = true; - } - _ref = tokens.slice(i - 1, (i + 1) + 1 || 9e9), prev = _ref[0], current = _ref[1], next = _ref[2]; - callObject = !noCall && tag === 'INDENT' && next && next.generated && next[0] === '{' && prev && (_ref1 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref1) >= 0); - seenSingle = false; - seenControl = false; - if (__indexOf.call(LINEBREAKS, tag) >= 0) { - noCall = false; - } - if (prev && !prev.spaced && tag === '?') { - token.call = true; - } - if (token.fromThen) { - return 1; - } - if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) { - return 1; - } - tokens.splice(i, 0, this.generate('CALL_START', '(', token[2])); - this.detectEnd(i + 1, condition, action); - if (prev[0] === '?') { - prev[0] = 'FUNC_EXIST'; - } - return 2; - }); - }; - - Rewriter.prototype.addImplicitIndentation = function() { - var action, condition, indent, outdent, starter; - starter = indent = outdent = null; - condition = function(token, i) { - var _ref; - return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'ELSE' && (starter !== 'IF' && starter !== 'THEN')); - }; - action = function(token, i) { - return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent); - }; - return this.scanTokens(function(token, i, tokens) { - var tag, _ref, _ref1; - tag = token[0]; - if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') { - tokens.splice(i, 1); - return 0; - } - if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { - tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation(token)))); - return 2; - } - if (tag === 'CATCH' && ((_ref = this.tag(i + 2)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) { - tokens.splice.apply(tokens, [i + 2, 0].concat(__slice.call(this.indentation(token)))); - return 4; - } - if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { - starter = tag; - _ref1 = this.indentation(token, true), indent = _ref1[0], outdent = _ref1[1]; - if (starter === 'THEN') { - indent.fromThen = true; - } - tokens.splice(i + 1, 0, indent); - this.detectEnd(i + 2, condition, action); - if (tag === 'THEN') { - tokens.splice(i, 1); - } - return 1; - } - return 1; - }); - }; - - Rewriter.prototype.tagPostfixConditionals = function() { - var action, condition, original; - original = null; - condition = function(token, i) { - var _ref; - return (_ref = token[0]) === 'TERMINATOR' || _ref === 'INDENT'; - }; - action = function(token, i) { - if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) { - return original[0] = 'POST_' + original[0]; - } - }; - return this.scanTokens(function(token, i) { - if (token[0] !== 'IF') { - return 1; - } - original = token; - this.detectEnd(i + 1, condition, action); - return 1; - }); - }; - - Rewriter.prototype.indentation = function(token, implicit) { - var indent, outdent; - if (implicit == null) { - implicit = false; - } - indent = ['INDENT', 2, token[2]]; - outdent = ['OUTDENT', 2, token[2]]; - if (implicit) { - indent.generated = outdent.generated = true; - } - return [indent, outdent]; - }; - - Rewriter.prototype.generate = function(tag, value, line) { - var tok; - tok = [tag, value, line]; - tok.generated = true; - return tok; - }; - - Rewriter.prototype.tag = function(i) { - var _ref; - return (_ref = this.tokens[i]) != null ? _ref[0] : void 0; - }; - - return Rewriter; - - })(); - - BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']]; - - exports.INVERSES = INVERSES = {}; - - EXPRESSION_START = []; - - EXPRESSION_END = []; - - for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) { - _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1]; - EXPRESSION_START.push(INVERSES[rite] = left); - EXPRESSION_END.push(INVERSES[left] = rite); - } - - EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); - - IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; - - IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', '@', '->', '=>', '[', '(', '{', '--', '++']; - - IMPLICIT_UNSPACED_CALL = ['+', '-']; - - IMPLICIT_BLOCK = ['->', '=>', '{', '[', ',']; - - IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR']; - - SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; - - SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']; - - LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js b/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js deleted file mode 100644 index 3efc4ede..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/lib/coffee-script/scope.js +++ /dev/null @@ -1,146 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Scope, extend, last, _ref; - - _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; - - exports.Scope = Scope = (function() { - - Scope.root = null; - - function Scope(parent, expressions, method) { - this.parent = parent; - this.expressions = expressions; - this.method = method; - this.variables = [ - { - name: 'arguments', - type: 'arguments' - } - ]; - this.positions = {}; - if (!this.parent) { - Scope.root = this; - } - } - - Scope.prototype.add = function(name, type, immediate) { - if (this.shared && !immediate) { - return this.parent.add(name, type, immediate); - } - if (Object.prototype.hasOwnProperty.call(this.positions, name)) { - return this.variables[this.positions[name]].type = type; - } else { - return this.positions[name] = this.variables.push({ - name: name, - type: type - }) - 1; - } - }; - - Scope.prototype.namedMethod = function() { - if (this.method.name || !this.parent) { - return this.method; - } - return this.parent.namedMethod(); - }; - - Scope.prototype.find = function(name) { - if (this.check(name)) { - return true; - } - this.add(name, 'var'); - return false; - }; - - Scope.prototype.parameter = function(name) { - if (this.shared && this.parent.check(name, true)) { - return; - } - return this.add(name, 'param'); - }; - - Scope.prototype.check = function(name) { - var _ref1; - return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0)); - }; - - Scope.prototype.temporary = function(name, index) { - if (name.length > 1) { - return '_' + name + (index > 1 ? index - 1 : ''); - } else { - return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a'); - } - }; - - Scope.prototype.type = function(name) { - var v, _i, _len, _ref1; - _ref1 = this.variables; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - v = _ref1[_i]; - if (v.name === name) { - return v.type; - } - } - return null; - }; - - Scope.prototype.freeVariable = function(name, reserve) { - var index, temp; - if (reserve == null) { - reserve = true; - } - index = 0; - while (this.check((temp = this.temporary(name, index)))) { - index++; - } - if (reserve) { - this.add(temp, 'var', true); - } - return temp; - }; - - Scope.prototype.assign = function(name, value) { - this.add(name, { - value: value, - assigned: true - }, true); - return this.hasAssignments = true; - }; - - Scope.prototype.hasDeclarations = function() { - return !!this.declaredVariables().length; - }; - - Scope.prototype.declaredVariables = function() { - var realVars, tempVars, v, _i, _len, _ref1; - realVars = []; - tempVars = []; - _ref1 = this.variables; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - v = _ref1[_i]; - if (v.type === 'var') { - (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name); - } - } - return realVars.sort().concat(tempVars.sort()); - }; - - Scope.prototype.assignedVariables = function() { - var v, _i, _len, _ref1, _results; - _ref1 = this.variables; - _results = []; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - v = _ref1[_i]; - if (v.type.assigned) { - _results.push("" + v.name + " = " + v.type.value); - } - } - return _results; - }; - - return Scope; - - })(); - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json b/spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json deleted file mode 100644 index 1fac7cae..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/coffee-script/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "coffee-script", - "description": "Unfancy JavaScript", - "keywords": [ - "javascript", - "language", - "coffeescript", - "compiler" - ], - "author": { - "name": "Jeremy Ashkenas" - }, - "version": "1.3.3", - "licenses": [ - { - "type": "MIT", - "url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE" - } - ], - "engines": { - "node": ">=0.4.0" - }, - "directories": { - "lib": "./lib/coffee-script" - }, - "main": "./lib/coffee-script/coffee-script", - "bin": { - "coffee": "./bin/coffee", - "cake": "./bin/cake" - }, - "homepage": "http://coffeescript.org", - "bugs": { - "url": "https://github.com/jashkenas/coffee-script/issues" - }, - "repository": { - "type": "git", - "url": "git://github.com/jashkenas/coffee-script.git" - }, - "devDependencies": { - "uglify-js": ">=1.0.0", - "jison": ">=0.2.0" - }, - "_npmUser": { - "name": "jashkenas", - "email": "jashkenas@gmail.com" - }, - "_id": "coffee-script@1.3.3", - "dependencies": {}, - "optionalDependencies": {}, - "_engineSupported": true, - "_npmVersion": "1.1.18", - "_nodeVersion": "v0.6.16", - "_defaultsLoaded": true, - "dist": { - "shasum": "150d6b4cb522894369efed6a2101c20bc7f4a4f4", - "tarball": "http://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz" - }, - "maintainers": [ - { - "name": "jashkenas", - "email": "jashkenas@gmail.com" - } - ], - "_shasum": "150d6b4cb522894369efed6a2101c20bc7f4a4f4", - "_from": "coffee-script@~1.3.3", - "_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt b/spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt deleted file mode 100644 index 7dca1070..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/MIT-LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2010 - -Marak Squires -Alexis Sellier (cloudhead) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md b/spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md deleted file mode 100644 index 0eda52db..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/ReadMe.md +++ /dev/null @@ -1,77 +0,0 @@ -# colors.js - get color and style in your node.js console ( and browser ) like what - - - - -## Installation - - npm install colors - -## colors and styles! - -- bold -- italic -- underline -- inverse -- yellow -- cyan -- white -- magenta -- green -- red -- grey -- blue -- rainbow -- zebra -- random - -## Usage - -``` js -var colors = require('./colors'); - -console.log('hello'.green); // outputs green text -console.log('i like cake and pies'.underline.red) // outputs red underlined text -console.log('inverse the color'.inverse); // inverses the color -console.log('OMG Rainbows!'.rainbow); // rainbow (ignores spaces) -``` - -# Creating Custom themes - -```js - -var colors = require('colors'); - -colors.setTheme({ - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red' -}); - -// outputs red text -console.log("this is an error".error); - -// outputs yellow text -console.log("this is a warning".warn); -``` - - -### Contributors - -Marak (Marak Squires) -Alexis Sellier (cloudhead) -mmalecki (Maciej MaÅ‚ecki) -nicoreed (Nico Reed) -morganrallen (Morgan Allen) -JustinCampbell (Justin Campbell) -ded (Dustin Diaz) - - -#### , Marak Squires , Justin Campbell, Dustin Diaz (@ded) diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/colors.js b/spec/fixture/node_modules/grunt/node_modules/colors/colors.js deleted file mode 100644 index 7a537d8d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/colors.js +++ /dev/null @@ -1,342 +0,0 @@ -/* -colors.js - -Copyright (c) 2010 - -Marak Squires -Alexis Sellier (cloudhead) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -var isHeadless = false; - -if (typeof module !== 'undefined') { - isHeadless = true; -} - -if (!isHeadless) { - var exports = {}; - var module = {}; - var colors = exports; - exports.mode = "browser"; -} else { - exports.mode = "console"; -} - -// -// Prototypes the string object to have additional method calls that add terminal colors -// -var addProperty = function (color, func) { - exports[color] = function (str) { - return func.apply(str); - }; - String.prototype.__defineGetter__(color, func); -}; - -function stylize(str, style) { - - var styles; - - if (exports.mode === 'console') { - styles = { - //styles - 'bold' : ['\x1B[1m', '\x1B[22m'], - 'italic' : ['\x1B[3m', '\x1B[23m'], - 'underline' : ['\x1B[4m', '\x1B[24m'], - 'inverse' : ['\x1B[7m', '\x1B[27m'], - 'strikethrough' : ['\x1B[9m', '\x1B[29m'], - //text colors - //grayscale - 'white' : ['\x1B[37m', '\x1B[39m'], - 'grey' : ['\x1B[90m', '\x1B[39m'], - 'black' : ['\x1B[30m', '\x1B[39m'], - //colors - 'blue' : ['\x1B[34m', '\x1B[39m'], - 'cyan' : ['\x1B[36m', '\x1B[39m'], - 'green' : ['\x1B[32m', '\x1B[39m'], - 'magenta' : ['\x1B[35m', '\x1B[39m'], - 'red' : ['\x1B[31m', '\x1B[39m'], - 'yellow' : ['\x1B[33m', '\x1B[39m'], - //background colors - //grayscale - 'whiteBG' : ['\x1B[47m', '\x1B[49m'], - 'greyBG' : ['\x1B[49;5;8m', '\x1B[49m'], - 'blackBG' : ['\x1B[40m', '\x1B[49m'], - //colors - 'blueBG' : ['\x1B[44m', '\x1B[49m'], - 'cyanBG' : ['\x1B[46m', '\x1B[49m'], - 'greenBG' : ['\x1B[42m', '\x1B[49m'], - 'magentaBG' : ['\x1B[45m', '\x1B[49m'], - 'redBG' : ['\x1B[41m', '\x1B[49m'], - 'yellowBG' : ['\x1B[43m', '\x1B[49m'] - }; - } else if (exports.mode === 'browser') { - styles = { - //styles - 'bold' : ['', ''], - 'italic' : ['', ''], - 'underline' : ['', ''], - 'inverse' : ['', ''], - 'strikethrough' : ['', ''], - //text colors - //grayscale - 'white' : ['', ''], - 'grey' : ['', ''], - 'black' : ['', ''], - //colors - 'blue' : ['', ''], - 'cyan' : ['', ''], - 'green' : ['', ''], - 'magenta' : ['', ''], - 'red' : ['', ''], - 'yellow' : ['', ''], - //background colors - //grayscale - 'whiteBG' : ['', ''], - 'greyBG' : ['', ''], - 'blackBG' : ['', ''], - //colors - 'blueBG' : ['', ''], - 'cyanBG' : ['', ''], - 'greenBG' : ['', ''], - 'magentaBG' : ['', ''], - 'redBG' : ['', ''], - 'yellowBG' : ['', ''] - }; - } else if (exports.mode === 'none') { - return str + ''; - } else { - console.log('unsupported mode, try "browser", "console" or "none"'); - } - return styles[style][0] + str + styles[style][1]; -} - -function applyTheme(theme) { - - // - // Remark: This is a list of methods that exist - // on String that you should not overwrite. - // - var stringPrototypeBlacklist = [ - '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'charAt', 'constructor', - 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf', 'charCodeAt', - 'indexOf', 'lastIndexof', 'length', 'localeCompare', 'match', 'replace', 'search', 'slice', 'split', 'substring', - 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight' - ]; - - Object.keys(theme).forEach(function (prop) { - if (stringPrototypeBlacklist.indexOf(prop) !== -1) { - console.log('warn: '.red + ('String.prototype' + prop).magenta + ' is probably something you don\'t want to override. Ignoring style name'); - } - else { - if (typeof(theme[prop]) === 'string') { - addProperty(prop, function () { - return exports[theme[prop]](this); - }); - } - else { - addProperty(prop, function () { - var ret = this; - for (var t = 0; t < theme[prop].length; t++) { - ret = exports[theme[prop][t]](ret); - } - return ret; - }); - } - } - }); -} - - -// -// Iterate through all default styles and colors -// -var x = ['bold', 'underline', 'strikethrough', 'italic', 'inverse', 'grey', 'black', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta', 'greyBG', 'blackBG', 'yellowBG', 'redBG', 'greenBG', 'blueBG', 'whiteBG', 'cyanBG', 'magentaBG']; -x.forEach(function (style) { - - // __defineGetter__ at the least works in more browsers - // http://robertnyman.com/javascript/javascript-getters-setters.html - // Object.defineProperty only works in Chrome - addProperty(style, function () { - return stylize(this, style); - }); -}); - -function sequencer(map) { - return function () { - if (!isHeadless) { - return this.replace(/( )/, '$1'); - } - var exploded = this.split(""), i = 0; - exploded = exploded.map(map); - return exploded.join(""); - }; -} - -var rainbowMap = (function () { - var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; //RoY G BiV - return function (letter, i, exploded) { - if (letter === " ") { - return letter; - } else { - return stylize(letter, rainbowColors[i++ % rainbowColors.length]); - } - }; -})(); - -exports.themes = {}; - -exports.addSequencer = function (name, map) { - addProperty(name, sequencer(map)); -}; - -exports.addSequencer('rainbow', rainbowMap); -exports.addSequencer('zebra', function (letter, i, exploded) { - return i % 2 === 0 ? letter : letter.inverse; -}); - -exports.setTheme = function (theme) { - if (typeof theme === 'string') { - try { - exports.themes[theme] = require(theme); - applyTheme(exports.themes[theme]); - return exports.themes[theme]; - } catch (err) { - console.log(err); - return err; - } - } else { - applyTheme(theme); - } -}; - - -addProperty('stripColors', function () { - return ("" + this).replace(/\x1B\[\d+m/g, ''); -}); - -// please no -function zalgo(text, options) { - var soul = { - "up" : [ - 'Ì', 'ÌŽ', 'Ì„', 'Ì…', - 'Ì¿', 'Ì‘', '̆', 'Ì', - 'Í’', 'Í—', 'Í‘', '̇', - '̈', 'ÌŠ', 'Í‚', 'Ì“', - '̈', 'ÍŠ', 'Í‹', 'ÍŒ', - '̃', 'Ì‚', 'ÌŒ', 'Í', - 'Ì€', 'Ì', 'Ì‹', 'Ì', - 'Ì’', 'Ì“', 'Ì”', '̽', - '̉', 'Í£', 'ͤ', 'Í¥', - 'ͦ', 'ͧ', 'ͨ', 'Í©', - 'ͪ', 'Í«', 'ͬ', 'Í­', - 'Í®', 'ͯ', '̾', 'Í›', - '͆', 'Ìš' - ], - "down" : [ - 'Ì–', 'Ì—', '̘', 'Ì™', - 'Ìœ', 'Ì', 'Ìž', 'ÌŸ', - 'Ì ', '̤', 'Ì¥', '̦', - 'Ì©', '̪', 'Ì«', '̬', - 'Ì­', 'Ì®', '̯', '̰', - '̱', '̲', '̳', '̹', - '̺', 'Ì»', '̼', 'Í…', - '͇', '͈', '͉', 'Í', - 'ÍŽ', 'Í“', 'Í”', 'Í•', - 'Í–', 'Í™', 'Íš', 'Ì£' - ], - "mid" : [ - 'Ì•', 'Ì›', 'Ì€', 'Ì', - '͘', 'Ì¡', 'Ì¢', '̧', - '̨', 'Ì´', '̵', '̶', - 'Íœ', 'Í', 'Íž', - 'ÍŸ', 'Í ', 'Í¢', '̸', - 'Ì·', 'Í¡', ' Ò‰' - ] - }, - all = [].concat(soul.up, soul.down, soul.mid), - zalgo = {}; - - function randomNumber(range) { - var r = Math.floor(Math.random() * range); - return r; - } - - function is_char(character) { - var bool = false; - all.filter(function (i) { - bool = (i === character); - }); - return bool; - } - - function heComes(text, options) { - var result = '', counts, l; - options = options || {}; - options["up"] = options["up"] || true; - options["mid"] = options["mid"] || true; - options["down"] = options["down"] || true; - options["size"] = options["size"] || "maxi"; - text = text.split(''); - for (l in text) { - if (is_char(l)) { - continue; - } - result = result + text[l]; - counts = {"up" : 0, "down" : 0, "mid" : 0}; - switch (options.size) { - case 'mini': - counts.up = randomNumber(8); - counts.min = randomNumber(2); - counts.down = randomNumber(8); - break; - case 'maxi': - counts.up = randomNumber(16) + 3; - counts.min = randomNumber(4) + 1; - counts.down = randomNumber(64) + 3; - break; - default: - counts.up = randomNumber(8) + 1; - counts.mid = randomNumber(6) / 2; - counts.down = randomNumber(8) + 1; - break; - } - - var arr = ["up", "mid", "down"]; - for (var d in arr) { - var index = arr[d]; - for (var i = 0 ; i <= counts[index]; i++) { - if (options[index]) { - result = result + soul[index][randomNumber(soul[index].length)]; - } - } - } - } - return result; - } - return heComes(text); -} - - -// don't summon zalgo -addProperty('zalgo', function () { - return zalgo(this); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/example.html b/spec/fixture/node_modules/grunt/node_modules/colors/example.html deleted file mode 100644 index 7a2ae605..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/example.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - Colors Example - - - - - - \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/example.js b/spec/fixture/node_modules/grunt/node_modules/colors/example.js deleted file mode 100644 index b1e03a4f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/example.js +++ /dev/null @@ -1,77 +0,0 @@ -var colors = require('./colors'); - -//colors.mode = "browser"; - -var test = colors.red("hopefully colorless output"); -console.log('Rainbows are fun!'.rainbow); -console.log('So '.italic + 'are'.underline + ' styles! '.bold + 'inverse'.inverse); // styles not widely supported -console.log('Chains are also cool.'.bold.italic.underline.red); // styles not widely supported -//console.log('zalgo time!'.zalgo); -console.log(test.stripColors); -console.log("a".grey + " b".black); -console.log("Zebras are so fun!".zebra); -console.log('background color attack!'.black.whiteBG) - -// -// Remark: .strikethrough may not work with Mac OS Terminal App -// -console.log("This is " + "not".strikethrough + " fun."); -console.log(colors.rainbow('Rainbows are fun!')); -console.log(colors.italic('So ') + colors.underline('are') + colors.bold(' styles! ') + colors.inverse('inverse')); // styles not widely supported -console.log(colors.bold(colors.italic(colors.underline(colors.red('Chains are also cool.'))))); // styles not widely supported -//console.log(colors.zalgo('zalgo time!')); -console.log(colors.stripColors(test)); -console.log(colors.grey("a") + colors.black(" b")); - -colors.addSequencer("america", function(letter, i, exploded) { - if(letter === " ") return letter; - switch(i%3) { - case 0: return letter.red; - case 1: return letter.white; - case 2: return letter.blue; - } -}); - -colors.addSequencer("random", (function() { - var available = ['bold', 'underline', 'italic', 'inverse', 'grey', 'yellow', 'red', 'green', 'blue', 'white', 'cyan', 'magenta']; - - return function(letter, i, exploded) { - return letter === " " ? letter : letter[available[Math.round(Math.random() * (available.length - 1))]]; - }; -})()); - -console.log("AMERICA! F--K YEAH!".america); -console.log("So apparently I've been to Mars, with all the little green men. But you know, I don't recall.".random); - -// -// Custom themes -// - -// Load theme with JSON literal -colors.setTheme({ - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red' -}); - -// outputs red text -console.log("this is an error".error); - -// outputs yellow text -console.log("this is a warning".warn); - -// outputs grey text -console.log("this is an input".input); - -// Load a theme from file -colors.setTheme('./themes/winston-dark.js'); - -console.log("this is an input".input); - diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/package.json b/spec/fixture/node_modules/grunt/node_modules/colors/package.json deleted file mode 100644 index 00a2f658..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "colors", - "description": "get colors in your node.js console like what", - "version": "0.6.2", - "author": { - "name": "Marak Squires" - }, - "homepage": "https://github.com/Marak/colors.js", - "bugs": { - "url": "https://github.com/Marak/colors.js/issues" - }, - "keywords": [ - "ansi", - "terminal", - "colors" - ], - "repository": { - "type": "git", - "url": "http://github.com/Marak/colors.js.git" - }, - "engines": { - "node": ">=0.1.90" - }, - "main": "colors", - "_id": "colors@0.6.2", - "dist": { - "shasum": "2423fe6678ac0c5dae8852e5d0e5be08c997abcc", - "tarball": "http://registry.npmjs.org/colors/-/colors-0.6.2.tgz" - }, - "_from": "colors@~0.6.2", - "_npmVersion": "1.2.30", - "_npmUser": { - "name": "marak", - "email": "marak.squires@gmail.com" - }, - "maintainers": [ - { - "name": "marak", - "email": "marak.squires@gmail.com" - } - ], - "directories": {}, - "_shasum": "2423fe6678ac0c5dae8852e5d0e5be08c997abcc", - "_resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "readme": "ERROR: No README data found!", - "scripts": {} -} diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/test.js b/spec/fixture/node_modules/grunt/node_modules/colors/test.js deleted file mode 100644 index c32417d6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/test.js +++ /dev/null @@ -1,70 +0,0 @@ -var assert = require('assert'), - colors = require('./colors'); - -var s = 'string'; - -function a(s, code) { - return '\x1B[' + code.toString() + 'm' + s + '\x1B[39m'; -} - -function aE(s, color, code) { - assert.equal(s[color], a(s, code)); - assert.equal(colors[color](s), a(s, code)); - assert.equal(s[color], colors[color](s)); - assert.equal(s[color].stripColors, s); - assert.equal(s[color].stripColors, colors.stripColors(s)); -} - -function h(s, color) { - return '' + s + ''; -} - -var stylesColors = ['white', 'black', 'blue', 'cyan', 'green', 'magenta', 'red', 'yellow']; -var stylesAll = stylesColors.concat(['bold', 'italic', 'underline', 'inverse', 'rainbow']); - -colors.mode = 'console'; -assert.equal(s.bold, '\x1B[1m' + s + '\x1B[22m'); -assert.equal(s.italic, '\x1B[3m' + s + '\x1B[23m'); -assert.equal(s.underline, '\x1B[4m' + s + '\x1B[24m'); -assert.equal(s.strikethrough, '\x1B[9m' + s + '\x1B[29m'); -assert.equal(s.inverse, '\x1B[7m' + s + '\x1B[27m'); -assert.ok(s.rainbow); -aE(s, 'white', 37); -aE(s, 'grey', 90); -aE(s, 'black', 30); -aE(s, 'blue', 34); -aE(s, 'cyan', 36); -aE(s, 'green', 32); -aE(s, 'magenta', 35); -aE(s, 'red', 31); -aE(s, 'yellow', 33); -assert.equal(s, 'string'); - -colors.setTheme({error:'red'}); - -assert.equal(typeof("astring".red),'string'); -assert.equal(typeof("astring".error),'string'); - -colors.mode = 'browser'; -assert.equal(s.bold, '' + s + ''); -assert.equal(s.italic, '' + s + ''); -assert.equal(s.underline, '' + s + ''); -assert.equal(s.strikethrough, '' + s + ''); -assert.equal(s.inverse, '' + s + ''); -assert.ok(s.rainbow); -stylesColors.forEach(function (color) { - assert.equal(s[color], h(s, color)); - assert.equal(colors[color](s), h(s, color)); -}); - -assert.equal(typeof("astring".red),'string'); -assert.equal(typeof("astring".error),'string'); - -colors.mode = 'none'; -stylesAll.forEach(function (style) { - assert.equal(s[style], s); - assert.equal(colors[style](s), s); -}); - -assert.equal(typeof("astring".red),'string'); -assert.equal(typeof("astring".error),'string'); diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js b/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js deleted file mode 100644 index 49a905ba..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-dark.js +++ /dev/null @@ -1,12 +0,0 @@ -module['exports'] = { - silly: 'rainbow', - input: 'black', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red' -}; \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js b/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js deleted file mode 100644 index 571972c1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/colors/themes/winston-light.js +++ /dev/null @@ -1,12 +0,0 @@ -module['exports'] = { - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red' -}; \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md b/spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md deleted file mode 100644 index d469e6d7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/dateformat/Readme.md +++ /dev/null @@ -1,67 +0,0 @@ -# node-dateformat - -A node.js package for Steven Levithan's excellent [dateFormat()][dateformat] function. - -## Modifications - -* Removed the `Date.prototype.format` method. Sorry folks, but extending native prototypes is for suckers. -* Added a `module.exports = dateFormat;` statement at the bottom - -## Usage - -As taken from Steven's post, modified to match the Modifications listed above: - - var dateFormat = require('dateformat'); - var now = new Date(); - - // Basic usage - dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT"); - // Saturday, June 9th, 2007, 5:46:21 PM - - // You can use one of several named masks - dateFormat(now, "isoDateTime"); - // 2007-06-09T17:46:21 - - // ...Or add your own - dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"'; - dateFormat(now, "hammerTime"); - // 17:46! Can't touch this! - - // When using the standalone dateFormat function, - // you can also provide the date as a string - dateFormat("Jun 9 2007", "fullDate"); - // Saturday, June 9, 2007 - - // Note that if you don't include the mask argument, - // dateFormat.masks.default is used - dateFormat(now); - // Sat Jun 09 2007 17:46:21 - - // And if you don't include the date argument, - // the current date and time is used - dateFormat(); - // Sat Jun 09 2007 17:46:22 - - // You can also skip the date argument (as long as your mask doesn't - // contain any numbers), in which case the current date/time is used - dateFormat("longTime"); - // 5:46:22 PM EST - - // And finally, you can convert local time to UTC time. Simply pass in - // true as an additional argument (no argument skipping allowed in this case): - dateFormat(now, "longTime", true); - // 10:46:21 PM UTC - - // ...Or add the prefix "UTC:" to your mask. - dateFormat(now, "UTC:h:MM:ss TT Z"); - // 10:46:21 PM UTC - - // You can also get the ISO 8601 week of the year: - dateFormat(now, "W"); - // 42 -## License - -(c) 2007-2009 Steven Levithan [stevenlevithan.com][stevenlevithan], MIT license. - -[dateformat]: http://blog.stevenlevithan.com/archives/date-time-format -[stevenlevithan]: http://stevenlevithan.com/ diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js b/spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js deleted file mode 100644 index 92294246..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/dateformat/lib/dateformat.js +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Date Format 1.2.3 - * (c) 2007-2009 Steven Levithan - * MIT license - * - * Includes enhancements by Scott Trenda - * and Kris Kowal - * - * Accepts a date, a mask, or a date and a mask. - * Returns a formatted version of the given date. - * The date defaults to the current date/time. - * The mask defaults to dateFormat.masks.default. - */ - -var dateFormat = function () { - var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZW]|"[^"]*"|'[^']*'/g, - timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, - timezoneClip = /[^-+\dA-Z]/g, - pad = function (val, len) { - val = String(val); - len = len || 2; - while (val.length < len) val = "0" + val; - return val; - }, - /** - * Get the ISO 8601 week number - * Based on comments from - * http://techblog.procurios.nl/k/n618/news/view/33796/14863/Calculate-ISO-8601-week-and-year-in-javascript.html - */ - getWeek = function (date) { - // Remove time components of date - var targetThursday = new Date(date.getFullYear(), date.getMonth(), date.getDate()); - - // Change date to Thursday same week - targetThursday.setDate(targetThursday.getDate() - ((targetThursday.getDay() + 6) % 7) + 3); - - // Take January 4th as it is always in week 1 (see ISO 8601) - var firstThursday = new Date(targetThursday.getFullYear(), 0, 4); - - // Change date to Thursday same week - firstThursday.setDate(firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3); - - // Check if daylight-saving-time-switch occured and correct for it - var ds = targetThursday.getTimezoneOffset()/firstThursday.getTimezoneOffset()-1; - targetThursday.setHours(targetThursday.getHours()+ds); - - // Number of weeks between target Thursday and first Thursday - var weekDiff = (targetThursday - firstThursday) / (86400000*7); - return 1 + weekDiff; - }; - - // Regexes and supporting functions are cached through closure - return function (date, mask, utc) { - var dF = dateFormat; - - // You can't provide utc if you skip other args (use the "UTC:" mask prefix) - if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) { - mask = date; - date = undefined; - } - - date = date || new Date; - - if(!(date instanceof Date)) { - date = new Date(date); - } - - if (isNaN(date)) { - throw TypeError("Invalid date"); - } - - mask = String(dF.masks[mask] || mask || dF.masks["default"]); - - // Allow setting the utc argument via the mask - if (mask.slice(0, 4) == "UTC:") { - mask = mask.slice(4); - utc = true; - } - - var _ = utc ? "getUTC" : "get", - d = date[_ + "Date"](), - D = date[_ + "Day"](), - m = date[_ + "Month"](), - y = date[_ + "FullYear"](), - H = date[_ + "Hours"](), - M = date[_ + "Minutes"](), - s = date[_ + "Seconds"](), - L = date[_ + "Milliseconds"](), - o = utc ? 0 : date.getTimezoneOffset(), - W = getWeek(date), - flags = { - d: d, - dd: pad(d), - ddd: dF.i18n.dayNames[D], - dddd: dF.i18n.dayNames[D + 7], - m: m + 1, - mm: pad(m + 1), - mmm: dF.i18n.monthNames[m], - mmmm: dF.i18n.monthNames[m + 12], - yy: String(y).slice(2), - yyyy: y, - h: H % 12 || 12, - hh: pad(H % 12 || 12), - H: H, - HH: pad(H), - M: M, - MM: pad(M), - s: s, - ss: pad(s), - l: pad(L, 3), - L: pad(L > 99 ? Math.round(L / 10) : L), - t: H < 12 ? "a" : "p", - tt: H < 12 ? "am" : "pm", - T: H < 12 ? "A" : "P", - TT: H < 12 ? "AM" : "PM", - Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""), - o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), - S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10], - W: W - }; - - return mask.replace(token, function ($0) { - return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1); - }); - }; -}(); - -// Some common format strings -dateFormat.masks = { - "default": "ddd mmm dd yyyy HH:MM:ss", - shortDate: "m/d/yy", - mediumDate: "mmm d, yyyy", - longDate: "mmmm d, yyyy", - fullDate: "dddd, mmmm d, yyyy", - shortTime: "h:MM TT", - mediumTime: "h:MM:ss TT", - longTime: "h:MM:ss TT Z", - isoDate: "yyyy-mm-dd", - isoTime: "HH:MM:ss", - isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", - isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" -}; - -// Internationalization strings -dateFormat.i18n = { - dayNames: [ - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" - ], - monthNames: [ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" - ] -}; - -/* -// For convenience... -Date.prototype.format = function (mask, utc) { - return dateFormat(this, mask, utc); -}; -*/ - -if (typeof exports !== "undefined") { - module.exports = dateFormat; -} diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/package.json b/spec/fixture/node_modules/grunt/node_modules/dateformat/package.json deleted file mode 100644 index 47cf7250..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/dateformat/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "dateformat", - "description": "A node.js package for Steven Levithan's excellent dateFormat() function.", - "maintainers": [ - { - "name": "felixge", - "email": "felix@debuggable.com" - } - ], - "homepage": "https://github.com/felixge/node-dateformat", - "author": { - "name": "Steven Levithan" - }, - "version": "1.0.2-1.2.3", - "main": "./lib/dateformat", - "dependencies": {}, - "devDependencies": {}, - "engines": { - "node": "*" - }, - "_npmJsonOpts": { - "file": "/Users/felix/.npm/dateformat/1.0.2-1.2.3/package/package.json", - "wscript": false, - "contributors": false, - "serverjs": false - }, - "_id": "dateformat@1.0.2-1.2.3", - "_engineSupported": true, - "_npmVersion": "1.0.26", - "_nodeVersion": "v0.4.10-pre", - "_defaultsLoaded": true, - "dist": { - "shasum": "b0220c02de98617433b72851cf47de3df2cdbee9", - "tarball": "http://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz" - }, - "scripts": {}, - "directories": {}, - "_shasum": "b0220c02de98617433b72851cf47de3df2cdbee9", - "_from": "dateformat@1.0.2-1.2.3", - "_resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js b/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js deleted file mode 100644 index d1ddbe81..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.js +++ /dev/null @@ -1,4 +0,0 @@ -var dateFormat = require('../lib/dateformat.js'); - -var val = process.argv[2] || new Date(); -console.log(dateFormat(val, 'W')); diff --git a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh b/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh deleted file mode 100644 index 3c3e69b3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/dateformat/test/test_weekofyear.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# this just takes php's date() function as a reference to check if week of year -# is calculated correctly in the range from 1970 .. 2038 by brute force... - -SEQ="seq" -SYSTEM=`uname` -if [ "$SYSTEM" = "Darwin" ]; then - SEQ="jot" -fi - -for YEAR in {1970..2038}; do - for MONTH in {1..12}; do - DAYS=$(cal $MONTH $YEAR | egrep "28|29|30|31" |tail -1 |awk '{print $NF}') - for DAY in $( $SEQ $DAYS ); do - DATE=$YEAR-$MONTH-$DAY - echo -n $DATE ... - NODEVAL=$(node test_weekofyear.js $DATE) - PHPVAL=$(php -r "echo intval(date('W', strtotime('$DATE')));") - if [ "$NODEVAL" -ne "$PHPVAL" ]; then - echo "MISMATCH: node: $NODEVAL vs php: $PHPVAL for date $DATE" - else - echo " OK" - fi - done - done -done diff --git a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md b/spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md deleted file mode 100644 index e1f6edd6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/README.md +++ /dev/null @@ -1,248 +0,0 @@ -[![build-status](https://www.codeship.io/projects/3ad58940-4c7d-0131-15d5-5a8cd3f550f8/status)](https://www.codeship.io/projects/11259) - -# SYNOPSIS - -EventEmitter2 is an implementation of the EventEmitter found in Node.js - -# DESCRIPTION - -### FEATURES - - Namespaces/Wildcards. - - Times To Listen (TTL), extends the `once` concept with `many`. - - Browser environment compatibility. - - Demonstrates good performance in benchmarks - -``` -EventEmitterHeatUp x 3,728,965 ops/sec \302\2610.68% (60 runs sampled) -EventEmitter x 2,822,904 ops/sec \302\2610.74% (63 runs sampled) -EventEmitter2 x 7,251,227 ops/sec \302\2610.55% (58 runs sampled) -EventEmitter2 (wild) x 3,220,268 ops/sec \302\2610.44% (65 runs sampled) -Fastest is EventEmitter2 -``` - -### Differences (Non breaking, compatible with existing EventEmitter) - - - The constructor takes a configuration object. - -```javascript - var EventEmitter2 = require('eventemitter2').EventEmitter2; - var server = new EventEmitter2({ - - // - // use wildcards. - // - wildcard: true, - - // - // the delimiter used to segment namespaces, defaults to `.`. - // - delimiter: '::', - - // - // if you want to emit the newListener event set to true. - // - newListener: false, - - // - // max listeners that can be assigned to an event, default 10. - // - maxListeners: 20 - }); -``` - - - Getting the actual event that fired. - -```javascript - server.on('foo.*', function(value1, value2) { - console.log(this.event, value1, value2); - }); -``` - - - Fire an event N times and then remove it, an extension of the `once` concept. - -```javascript - server.many('foo', 4, function() { - console.log('hello'); - }); -``` - - - Pass in a namespaced event as an array rather than a delimited string. - -```javascript - server.many(['foo', 'bar', 'bazz'], function() { - console.log('hello'); - }); -``` - - -# API - -When an `EventEmitter` instance experiences an error, the typical action is -to emit an `error` event. Error events are treated as a special case. -If there is no listener for it, then the default action is to print a stack -trace and exit the program. - -All EventEmitters emit the event `newListener` when new listeners are -added. - - -**Namespaces** with **Wildcards** -To use namespaces/wildcards, pass the `wildcard` option into the EventEmitter -constructor. When namespaces/wildcards are enabled, events can either be -strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The -delimiter is also configurable as a constructor option. - -An event name passed to any event emitter method can contain a wild card (the -`*` character). If the event name is a string, a wildcard may appear as `foo.*`. -If the event name is an array, the wildcard may appear as `['foo', '*']`. - -If either of the above described events were passed to the `on` method, -subsequent emits such as the following would be observed... - -```javascript - emitter.emit('foo.bazz'); - emitter.emit(['foo', 'bar']); -``` - - -### emitter.addListener(event, listener) -### emitter.on(event, listener) - -Adds a listener to the end of the listeners array for the specified event. - -```javascript - server.on('data', function(value1, value2, value3, ...) { - console.log('The event was raised!'); - }); -``` - -```javascript - server.on('data', function(value) { - console.log('The event was raised!'); - }); -``` - -### emitter.onAny(listener) - -Adds a listener that will be fired when any event is emitted. - -```javascript - server.onAny(function(value) { - console.log('All events trigger this.'); - }); -``` - -### emitter.offAny(listener) - -Removes the listener that will be fired when any event is emitted. - -```javascript - server.offAny(function(value) { - console.log('The event was raised!'); - }); -``` - -#### emitter.once(event, listener) - -Adds a **one time** listener for the event. The listener is invoked -only the first time the event is fired, after which it is removed. - -```javascript - server.once('get', function (value) { - console.log('Ah, we have our first value!'); - }); -``` - -### emitter.many(event, timesToListen, listener) - -Adds a listener that will execute **n times** for the event before being -removed. The listener is invoked only the first **n times** the event is -fired, after which it is removed. - -```javascript - server.many('get', 4, function (value) { - console.log('This event will be listened to exactly four times.'); - }); -``` - - -### emitter.removeListener(event, listener) -### emitter.off(event, listener) - -Remove a listener from the listener array for the specified event. -**Caution**: changes array indices in the listener array behind the listener. - -```javascript - var callback = function(value) { - console.log('someone connected!'); - }; - server.on('get', callback); - // ... - server.removeListener('get', callback); -``` - - -### emitter.removeAllListeners([event]) - -Removes all listeners, or those of the specified event. - - -### emitter.setMaxListeners(n) - -By default EventEmitters will print a warning if more than 10 listeners -are added to it. This is a useful default which helps finding memory leaks. -Obviously not all Emitters should be limited to 10. This function allows -that to be increased. Set to zero for unlimited. - - -### emitter.listeners(event) - -Returns an array of listeners for the specified event. This array can be -manipulated, e.g. to remove listeners. - -```javascript - server.on('get', function(value) { - console.log('someone connected!'); - }); - console.log(server.listeners('get')); // [ [Function] ] -``` - -### emitter.listenersAny() - -Returns an array of listeners that are listening for any event that is -specified. This array can be manipulated, e.g. to remove listeners. - -```javascript - server.onAny(function(value) { - console.log('someone connected!'); - }); - console.log(server.listenersAny()[0]); // [ [Function] ] -``` - -### emitter.emit(event, [arg1], [arg2], [...]) - -Execute each of the listeners that may be listening for the specified event -name in order with the list of arguments. - -# LICENSE - -(The MIT License) - -Copyright (c) 2011 hij1nx - -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/spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js b/spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js deleted file mode 100644 index 6f583b5f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/eventemitter2'); diff --git a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js b/spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js deleted file mode 100644 index bde69e85..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/eventemitter2/lib/eventemitter2.js +++ /dev/null @@ -1,573 +0,0 @@ -/*! - * EventEmitter2 - * https://github.com/hij1nx/EventEmitter2 - * - * Copyright (c) 2013 hij1nx - * Licensed under the MIT license. - */ -;!function(undefined) { - - var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { - return Object.prototype.toString.call(obj) === "[object Array]"; - }; - var defaultMaxListeners = 10; - - function init() { - this._events = {}; - if (this._conf) { - configure.call(this, this._conf); - } - } - - function configure(conf) { - if (conf) { - - this._conf = conf; - - conf.delimiter && (this.delimiter = conf.delimiter); - conf.maxListeners && (this._events.maxListeners = conf.maxListeners); - conf.wildcard && (this.wildcard = conf.wildcard); - conf.newListener && (this.newListener = conf.newListener); - - if (this.wildcard) { - this.listenerTree = {}; - } - } - } - - function EventEmitter(conf) { - this._events = {}; - this.newListener = false; - configure.call(this, conf); - } - - // - // Attention, function return type now is array, always ! - // It has zero elements if no any matches found and one or more - // elements (leafs) if there are matches - // - function searchListenerTree(handlers, type, tree, i) { - if (!tree) { - return []; - } - var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, - typeLength = type.length, currentType = type[i], nextType = type[i+1]; - if (i === typeLength && tree._listeners) { - // - // If at the end of the event(s) list and the tree has listeners - // invoke those listeners. - // - if (typeof tree._listeners === 'function') { - handlers && handlers.push(tree._listeners); - return [tree]; - } else { - for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { - handlers && handlers.push(tree._listeners[leaf]); - } - return [tree]; - } - } - - if ((currentType === '*' || currentType === '**') || tree[currentType]) { - // - // If the event emitted is '*' at this part - // or there is a concrete match at this patch - // - if (currentType === '*') { - for (branch in tree) { - if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); - } - } - return listeners; - } else if(currentType === '**') { - endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); - if(endReached && tree._listeners) { - // The next element has a _listeners, add it to the handlers. - listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); - } - - for (branch in tree) { - if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { - if(branch === '*' || branch === '**') { - if(tree[branch]._listeners && !endReached) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); - } - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); - } else if(branch === nextType) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); - } else { - // No match on this one, shift into the tree but not in the type array. - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); - } - } - } - return listeners; - } - - listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); - } - - xTree = tree['*']; - if (xTree) { - // - // If the listener tree will allow any match for this part, - // then recursively explore all branches of the tree - // - searchListenerTree(handlers, type, xTree, i+1); - } - - xxTree = tree['**']; - if(xxTree) { - if(i < typeLength) { - if(xxTree._listeners) { - // If we have a listener on a '**', it will catch all, so add its handler. - searchListenerTree(handlers, type, xxTree, typeLength); - } - - // Build arrays of matching next branches and others. - for(branch in xxTree) { - if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { - if(branch === nextType) { - // We know the next element will match, so jump twice. - searchListenerTree(handlers, type, xxTree[branch], i+2); - } else if(branch === currentType) { - // Current node matches, move into the tree. - searchListenerTree(handlers, type, xxTree[branch], i+1); - } else { - isolatedBranch = {}; - isolatedBranch[branch] = xxTree[branch]; - searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); - } - } - } - } else if(xxTree._listeners) { - // We have reached the end and still on a '**' - searchListenerTree(handlers, type, xxTree, typeLength); - } else if(xxTree['*'] && xxTree['*']._listeners) { - searchListenerTree(handlers, type, xxTree['*'], typeLength); - } - } - - return listeners; - } - - function growListenerTree(type, listener) { - - type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - - // - // Looks for two consecutive '**', if so, don't add the event at all. - // - for(var i = 0, len = type.length; i+1 < len; i++) { - if(type[i] === '**' && type[i+1] === '**') { - return; - } - } - - var tree = this.listenerTree; - var name = type.shift(); - - while (name) { - - if (!tree[name]) { - tree[name] = {}; - } - - tree = tree[name]; - - if (type.length === 0) { - - if (!tree._listeners) { - tree._listeners = listener; - } - else if(typeof tree._listeners === 'function') { - tree._listeners = [tree._listeners, listener]; - } - else if (isArray(tree._listeners)) { - - tree._listeners.push(listener); - - if (!tree._listeners.warned) { - - var m = defaultMaxListeners; - - if (typeof this._events.maxListeners !== 'undefined') { - m = this._events.maxListeners; - } - - if (m > 0 && tree._listeners.length > m) { - - tree._listeners.warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - tree._listeners.length); - console.trace(); - } - } - } - return true; - } - name = type.shift(); - } - return true; - } - - // By default EventEmitters will print a warning if more than - // 10 listeners are added to it. This is a useful default which - // helps finding memory leaks. - // - // Obviously not all Emitters should be limited to 10. This function allows - // that to be increased. Set to zero for unlimited. - - EventEmitter.prototype.delimiter = '.'; - - EventEmitter.prototype.setMaxListeners = function(n) { - this._events || init.call(this); - this._events.maxListeners = n; - if (!this._conf) this._conf = {}; - this._conf.maxListeners = n; - }; - - EventEmitter.prototype.event = ''; - - EventEmitter.prototype.once = function(event, fn) { - this.many(event, 1, fn); - return this; - }; - - EventEmitter.prototype.many = function(event, ttl, fn) { - var self = this; - - if (typeof fn !== 'function') { - throw new Error('many only accepts instances of Function'); - } - - function listener() { - if (--ttl === 0) { - self.off(event, listener); - } - fn.apply(this, arguments); - } - - listener._origin = fn; - - this.on(event, listener); - - return self; - }; - - EventEmitter.prototype.emit = function() { - - this._events || init.call(this); - - var type = arguments[0]; - - if (type === 'newListener' && !this.newListener) { - if (!this._events.newListener) { return false; } - } - - // Loop through the *_all* functions and invoke them. - if (this._all) { - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - for (i = 0, l = this._all.length; i < l; i++) { - this.event = type; - this._all[i].apply(this, args); - } - } - - // If there is no 'error' event listener then throw. - if (type === 'error') { - - if (!this._all && - !this._events.error && - !(this.wildcard && this.listenerTree.error)) { - - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error("Uncaught, unspecified 'error' event."); - } - return false; - } - } - - var handler; - - if(this.wildcard) { - handler = []; - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - searchListenerTree.call(this, handler, ns, this.listenerTree, 0); - } - else { - handler = this._events[type]; - } - - if (typeof handler === 'function') { - this.event = type; - if (arguments.length === 1) { - handler.call(this); - } - else if (arguments.length > 1) - switch (arguments.length) { - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - handler.apply(this, args); - } - return true; - } - else if (handler) { - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { - this.event = type; - listeners[i].apply(this, args); - } - return (listeners.length > 0) || !!this._all; - } - else { - return !!this._all; - } - - }; - - EventEmitter.prototype.on = function(type, listener) { - - if (typeof type === 'function') { - this.onAny(type); - return this; - } - - if (typeof listener !== 'function') { - throw new Error('on only accepts instances of Function'); - } - this._events || init.call(this); - - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); - - if(this.wildcard) { - growListenerTree.call(this, type, listener); - return this; - } - - if (!this._events[type]) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } - else if(typeof this._events[type] === 'function') { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } - else if (isArray(this._events[type])) { - // If we've already got an array, just append. - this._events[type].push(listener); - - // Check for listener leak - if (!this._events[type].warned) { - - var m = defaultMaxListeners; - - if (typeof this._events.maxListeners !== 'undefined') { - m = this._events.maxListeners; - } - - if (m > 0 && this._events[type].length > m) { - - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - } - return this; - }; - - EventEmitter.prototype.onAny = function(fn) { - - if (typeof fn !== 'function') { - throw new Error('onAny only accepts instances of Function'); - } - - if(!this._all) { - this._all = []; - } - - // Add the function to the event listener collection. - this._all.push(fn); - return this; - }; - - EventEmitter.prototype.addListener = EventEmitter.prototype.on; - - EventEmitter.prototype.off = function(type, listener) { - if (typeof listener !== 'function') { - throw new Error('removeListener only takes instances of Function'); - } - - var handlers,leafs=[]; - - if(this.wildcard) { - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); - } - else { - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events[type]) return this; - handlers = this._events[type]; - leafs.push({_listeners:handlers}); - } - - for (var iLeaf=0; iLeaf 0) { - fns = this._all; - for(i = 0, l = fns.length; i < l; i++) { - if(fn === fns[i]) { - fns.splice(i, 1); - return this; - } - } - } else { - this._all = []; - } - return this; - }; - - EventEmitter.prototype.removeListener = EventEmitter.prototype.off; - - EventEmitter.prototype.removeAllListeners = function(type) { - if (arguments.length === 0) { - !this._events || init.call(this); - return this; - } - - if(this.wildcard) { - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); - - for (var iLeaf=0; iLeaf= 0.2.2" - }, - "main": "./lib/eventemitter2.js", - "scripts": { - "test": "nodeunit test/simple/ && nodeunit test/wildcardEvents/", - "benchmark": "node test/perf/benchmark.js" - }, - "files": [ - "lib/eventemitter2.js", - "index.js" - ], - "bugs": { - "url": "https://github.com/hij1nx/EventEmitter2/issues" - }, - "homepage": "https://github.com/hij1nx/EventEmitter2", - "_id": "eventemitter2@0.4.14", - "_shasum": "8f61b75cde012b2e9eb284d4545583b5643b61ab", - "_from": "eventemitter2@~0.4.13", - "_npmVersion": "1.4.7", - "_npmUser": { - "name": "jasonkuhrt", - "email": "jasonkuhrt@me.com" - }, - "maintainers": [ - { - "name": "hij1nx", - "email": "hij1nx@me.com" - }, - { - "name": "jasonkuhrt", - "email": "jasonkuhrt@me.com" - } - ], - "dist": { - "shasum": "8f61b75cde012b2e9eb284d4545583b5643b61ab", - "tarball": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc b/spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc deleted file mode 100644 index 2b7e39bf..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/.jshintrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "curly": true, - "eqeqeq": true, - "immed": true, - "latedef": "nofunc", - "newcap": true, - "noarg": true, - "sub": true, - "undef": true, - "unused": true, - "boss": true, - "eqnull": true, - "node": true -} diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/.npmignore b/spec/fixture/node_modules/grunt/node_modules/exit/.npmignore deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml deleted file mode 100644 index 42d43029..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: node_js -node_js: - - 0.8 - - '0.10' -before_script: - - npm install -g grunt-cli diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js b/spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js deleted file mode 100644 index ff37751b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/Gruntfile.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; - -module.exports = function(grunt) { - - // Project configuration. - grunt.initConfig({ - nodeunit: { - files: ['test/**/*_test.js'], - }, - jshint: { - options: { - jshintrc: '.jshintrc' - }, - gruntfile: { - src: 'Gruntfile.js' - }, - lib: { - src: ['lib/**/*.js'] - }, - test: { - src: ['test/**/*.js'] - }, - }, - watch: { - gruntfile: { - files: '<%= jshint.gruntfile.src %>', - tasks: ['jshint:gruntfile'] - }, - lib: { - files: '<%= jshint.lib.src %>', - tasks: ['jshint:lib', 'nodeunit'] - }, - test: { - files: '<%= jshint.test.src %>', - tasks: ['jshint:test', 'nodeunit'] - }, - }, - }); - - // These plugins provide necessary tasks. - grunt.loadNpmTasks('grunt-contrib-nodeunit'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-watch'); - - // Default task. - grunt.registerTask('default', ['jshint', 'nodeunit']); - -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT b/spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT deleted file mode 100644 index bb2aad6d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 "Cowboy" Ben Alman - -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/spec/fixture/node_modules/grunt/node_modules/exit/README.md b/spec/fixture/node_modules/grunt/node_modules/exit/README.md deleted file mode 100644 index 20c364eb..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit) - -A replacement for process.exit that ensures stdio are fully drained before exiting. - -To make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`. - -See [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference. - -Tested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18. - -Based on some code by [@vladikoff](https://github.com/vladikoff). - -## Getting Started -Install the module with: `npm install exit` - -```javascript -var exit = require('exit'); - -// These lines should appear in the output, EVEN ON WINDOWS. -console.log("omg"); -console.error("yay"); - -// process.exit(5); -exit(5); - -// These lines shouldn't appear in the output. -console.log("wtf"); -console.error("bro"); -``` - -## Don't believe me? Try it for yourself. - -In Windows, clone the repo and cd to the `test\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly. - -This test was done using cmd.exe, but you can see the same results using `| grep "std"` in either PowerShell or git-bash. - -``` -C:\node-exit\test\fixtures>node log.js 0 10 stdout stderr 2>&1 | find "std" -stdout 0 -stderr 0 -stdout 1 -stderr 1 -stdout 2 -stderr 2 -stdout 3 -stderr 3 -stdout 4 -stderr 4 -stdout 5 -stderr 5 -stdout 6 -stderr 6 -stdout 7 -stderr 7 -stdout 8 -stderr 8 -stdout 9 -stderr 9 - -C:\node-exit\test\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find "std" - -C:\node-exit\test\fixtures> -``` - -## Contributing -In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). - -## Release History -2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. -2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! -2013-09-20 - v0.1.0 - Initial release. - -## License -Copyright (c) 2013 "Cowboy" Ben Alman -Licensed under the MIT license. diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js b/spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js deleted file mode 100644 index 2883e059..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/lib/exit.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * exit - * https://github.com/cowboy/node-exit - * - * Copyright (c) 2013 "Cowboy" Ben Alman - * Licensed under the MIT license. - */ - -'use strict'; - -module.exports = function exit(exitCode, streams) { - if (!streams) { streams = [process.stdout, process.stderr]; } - var drainCount = 0; - // Actually exit if all streams are drained. - function tryToExit() { - if (drainCount === streams.length) { - process.exit(exitCode); - } - } - streams.forEach(function(stream) { - // Count drained streams now, but monitor non-drained streams. - if (stream.bufferSize === 0) { - drainCount++; - } else { - stream.write('', 'utf-8', function() { - drainCount++; - tryToExit(); - }); - } - // Prevent further writing. - stream.write = function() {}; - }); - // If all streams were already drained, exit now. - tryToExit(); - // In Windows, when run as a Node.js child process, a script utilizing - // this library might just exit with a 0 exit code, regardless. This code, - // despite the fact that it looks a bit crazy, appears to fix that. - process.on('exit', function() { - process.exit(exitCode); - }); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/package.json b/spec/fixture/node_modules/grunt/node_modules/exit/package.json deleted file mode 100644 index eb27d998..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "exit", - "description": "A replacement for process.exit that ensures stdio are fully drained before exiting.", - "version": "0.1.2", - "homepage": "https://github.com/cowboy/node-exit", - "author": { - "name": "\"Cowboy\" Ben Alman", - "url": "http://benalman.com/" - }, - "repository": { - "type": "git", - "url": "git://github.com/cowboy/node-exit.git" - }, - "bugs": { - "url": "https://github.com/cowboy/node-exit/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/cowboy/node-exit/blob/master/LICENSE-MIT" - } - ], - "main": "lib/exit", - "engines": { - "node": ">= 0.8.0" - }, - "scripts": { - "test": "grunt nodeunit" - }, - "devDependencies": { - "grunt-contrib-jshint": "~0.6.4", - "grunt-contrib-nodeunit": "~0.2.0", - "grunt-contrib-watch": "~0.5.3", - "grunt": "~0.4.1", - "which": "~1.0.5" - }, - "keywords": [ - "exit", - "process", - "stdio", - "stdout", - "stderr", - "drain", - "flush", - "3584" - ], - "readme": "# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit)\n\nA replacement for process.exit that ensures stdio are fully drained before exiting.\n\nTo make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.\n\nSee [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.\n\nTested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.\n\nBased on some code by [@vladikoff](https://github.com/vladikoff).\n\n## Getting Started\nInstall the module with: `npm install exit`\n\n```javascript\nvar exit = require('exit');\n\n// These lines should appear in the output, EVEN ON WINDOWS.\nconsole.log(\"omg\");\nconsole.error(\"yay\");\n\n// process.exit(5);\nexit(5);\n\n// These lines shouldn't appear in the output.\nconsole.log(\"wtf\");\nconsole.error(\"bro\");\n```\n\n## Don't believe me? Try it for yourself.\n\nIn Windows, clone the repo and cd to the `test\\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.\n\nThis test was done using cmd.exe, but you can see the same results using `| grep \"std\"` in either PowerShell or git-bash.\n\n```\nC:\\node-exit\\test\\fixtures>node log.js 0 10 stdout stderr 2>&1 | find \"std\"\nstdout 0\nstderr 0\nstdout 1\nstderr 1\nstdout 2\nstderr 2\nstdout 3\nstderr 3\nstdout 4\nstderr 4\nstdout 5\nstderr 5\nstdout 6\nstderr 6\nstdout 7\nstderr 7\nstdout 8\nstderr 8\nstdout 9\nstderr 9\n\nC:\\node-exit\\test\\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find \"std\"\n\nC:\\node-exit\\test\\fixtures>\n```\n\n## Contributing\nIn lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).\n\n## Release History\n2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. \n2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! \n2013-09-20 - v0.1.0 - Initial release.\n\n## License\nCopyright (c) 2013 \"Cowboy\" Ben Alman \nLicensed under the MIT license.\n", - "readmeFilename": "README.md", - "_id": "exit@0.1.2", - "dist": { - "shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", - "tarball": "http://registry.npmjs.org/exit/-/exit-0.1.2.tgz" - }, - "_from": "exit@~0.1.1", - "_npmVersion": "1.3.11", - "_npmUser": { - "name": "cowboy", - "email": "cowboy@rj3.net" - }, - "maintainers": [ - { - "name": "cowboy", - "email": "cowboy@rj3.net" - } - ], - "directories": {}, - "_shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", - "_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js b/spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js deleted file mode 100644 index a91afb91..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/exit_test.js +++ /dev/null @@ -1,121 +0,0 @@ -'use strict'; - -/* - ======== A Handy Little Nodeunit Reference ======== - https://github.com/caolan/nodeunit - - Test methods: - test.expect(numAssertions) - test.done() - Test assertions: - test.ok(value, [message]) - test.equal(actual, expected, [message]) - test.notEqual(actual, expected, [message]) - test.deepEqual(actual, expected, [message]) - test.notDeepEqual(actual, expected, [message]) - test.strictEqual(actual, expected, [message]) - test.notStrictEqual(actual, expected, [message]) - test.throws(block, [error], [message]) - test.doesNotThrow(block, [error], [message]) - test.ifError(value) -*/ - -var fs = require('fs'); -var exec = require('child_process').exec; - -var _which = require('which').sync; -function which(command) { - try { - _which(command); - return command; - } catch (err) { - return false; - } -} - -// Look for grep first (any OS). If not found (but on Windows) look for find, -// which is Windows' horribly crippled grep alternative. -var grep = which('grep') || process.platform === 'win32' && which('find'); - -exports['exit'] = { - setUp: function(done) { - this.origCwd = process.cwd(); - process.chdir('test/fixtures'); - done(); - }, - tearDown: function(done) { - process.chdir(this.origCwd); - done(); - }, - 'grep': function(test) { - test.expect(1); - // Many unit tests depend on this. - test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.'); - test.done(); - }, - // The rest of the tests are built dynamically, to keep things sane. -}; - -// A few helper functions. -function normalizeLineEndings(s) { - return s.replace(/\r?\n/g, '\n'); -} - -// Capture command output, normalizing captured stdout to unix file endings. -function run(command, callback) { - exec(command, function(error, stdout) { - callback(error ? error.code : 0, normalizeLineEndings(stdout)); - }); -} - -// Read a fixture file, normalizing file contents to unix file endings. -function fixture(filename) { - return normalizeLineEndings(String(fs.readFileSync(filename))); -} - -function buildTests() { - // Build individual unit tests for command output. - var counts = [10, 100, 1000]; - var outputs = [' stdout stderr', ' stdout', ' stderr']; - var pipes = ['', ' | ' + grep + ' "std"']; - counts.forEach(function(count) { - outputs.forEach(function(output) { - pipes.forEach(function(pipe) { - var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe; - exports['exit']['output (' + command + ')'] = function(test) { - test.expect(2); - run(command, function(code, actual) { - var expected = fixture(count + output.replace(/ /g, '-') + '.txt'); - // Sometimes, the actual file lines are out of order on Windows. - // But since the point of this lib is to drain the buffer and not - // guarantee output order, we only test the length. - test.equal(actual.length, expected.length, 'should be the same length.'); - // The "fail" lines in log.js should NOT be output! - test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.'); - test.done(); - }); - }; - }); - }); - }); - - // Build individual unit tests for exit codes. - var codes = [0, 1, 123]; - codes.forEach(function(code) { - var command = 'node log.js ' + code + ' 10 stdout stderr'; - exports['exit']['exit code (' + command + ')'] = function(test) { - test.expect(1); - run(command, function(actual) { - // The specified exit code should be passed through. - test.equal(actual, code, 'should exit with ' + code + ' error code.'); - test.done(); - }); - }; - }); -} - -// Don't bother building tests if grep wasn't found, otherwise everything will -// fail and the error will get lost. -if (grep) { - buildTests(); -} diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt deleted file mode 100644 index 28592003..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stderr.txt +++ /dev/null @@ -1,10 +0,0 @@ -stderr 0 -stderr 1 -stderr 2 -stderr 3 -stderr 4 -stderr 5 -stderr 6 -stderr 7 -stderr 8 -stderr 9 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt deleted file mode 100644 index 9de86166..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout-stderr.txt +++ /dev/null @@ -1,20 +0,0 @@ -stdout 0 -stderr 0 -stdout 1 -stdout 2 -stderr 1 -stdout 3 -stderr 2 -stderr 3 -stdout 4 -stderr 4 -stdout 5 -stderr 5 -stdout 6 -stderr 6 -stdout 7 -stderr 7 -stdout 8 -stderr 8 -stdout 9 -stderr 9 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt deleted file mode 100644 index 1ce90dcc..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/10-stdout.txt +++ /dev/null @@ -1,10 +0,0 @@ -stdout 0 -stdout 1 -stdout 2 -stdout 3 -stdout 4 -stdout 5 -stdout 6 -stdout 7 -stdout 8 -stdout 9 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt deleted file mode 100644 index 3a78c857..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stderr.txt +++ /dev/null @@ -1,100 +0,0 @@ -stderr 0 -stderr 1 -stderr 2 -stderr 3 -stderr 4 -stderr 5 -stderr 6 -stderr 7 -stderr 8 -stderr 9 -stderr 10 -stderr 11 -stderr 12 -stderr 13 -stderr 14 -stderr 15 -stderr 16 -stderr 17 -stderr 18 -stderr 19 -stderr 20 -stderr 21 -stderr 22 -stderr 23 -stderr 24 -stderr 25 -stderr 26 -stderr 27 -stderr 28 -stderr 29 -stderr 30 -stderr 31 -stderr 32 -stderr 33 -stderr 34 -stderr 35 -stderr 36 -stderr 37 -stderr 38 -stderr 39 -stderr 40 -stderr 41 -stderr 42 -stderr 43 -stderr 44 -stderr 45 -stderr 46 -stderr 47 -stderr 48 -stderr 49 -stderr 50 -stderr 51 -stderr 52 -stderr 53 -stderr 54 -stderr 55 -stderr 56 -stderr 57 -stderr 58 -stderr 59 -stderr 60 -stderr 61 -stderr 62 -stderr 63 -stderr 64 -stderr 65 -stderr 66 -stderr 67 -stderr 68 -stderr 69 -stderr 70 -stderr 71 -stderr 72 -stderr 73 -stderr 74 -stderr 75 -stderr 76 -stderr 77 -stderr 78 -stderr 79 -stderr 80 -stderr 81 -stderr 82 -stderr 83 -stderr 84 -stderr 85 -stderr 86 -stderr 87 -stderr 88 -stderr 89 -stderr 90 -stderr 91 -stderr 92 -stderr 93 -stderr 94 -stderr 95 -stderr 96 -stderr 97 -stderr 98 -stderr 99 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt deleted file mode 100644 index 65f35f45..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout-stderr.txt +++ /dev/null @@ -1,200 +0,0 @@ -stdout 0 -stderr 0 -stdout 1 -stderr 1 -stdout 2 -stderr 2 -stdout 3 -stderr 3 -stdout 4 -stderr 4 -stdout 5 -stderr 5 -stdout 6 -stderr 6 -stdout 7 -stderr 7 -stdout 8 -stderr 8 -stdout 9 -stderr 9 -stdout 10 -stderr 10 -stdout 11 -stderr 11 -stdout 12 -stderr 12 -stdout 13 -stderr 13 -stdout 14 -stderr 14 -stdout 15 -stderr 15 -stdout 16 -stderr 16 -stdout 17 -stderr 17 -stdout 18 -stderr 18 -stdout 19 -stderr 19 -stdout 20 -stderr 20 -stdout 21 -stderr 21 -stdout 22 -stderr 22 -stdout 23 -stderr 23 -stdout 24 -stderr 24 -stdout 25 -stderr 25 -stdout 26 -stderr 26 -stdout 27 -stderr 27 -stdout 28 -stderr 28 -stdout 29 -stderr 29 -stdout 30 -stderr 30 -stdout 31 -stderr 31 -stdout 32 -stderr 32 -stdout 33 -stderr 33 -stdout 34 -stderr 34 -stdout 35 -stderr 35 -stdout 36 -stderr 36 -stdout 37 -stderr 37 -stdout 38 -stderr 38 -stdout 39 -stderr 39 -stdout 40 -stderr 40 -stdout 41 -stderr 41 -stdout 42 -stderr 42 -stdout 43 -stderr 43 -stdout 44 -stderr 44 -stdout 45 -stderr 45 -stdout 46 -stderr 46 -stdout 47 -stderr 47 -stdout 48 -stderr 48 -stdout 49 -stderr 49 -stdout 50 -stderr 50 -stdout 51 -stderr 51 -stdout 52 -stderr 52 -stdout 53 -stderr 53 -stdout 54 -stderr 54 -stdout 55 -stderr 55 -stdout 56 -stderr 56 -stdout 57 -stderr 57 -stdout 58 -stderr 58 -stdout 59 -stderr 59 -stdout 60 -stderr 60 -stdout 61 -stderr 61 -stdout 62 -stderr 62 -stdout 63 -stderr 63 -stdout 64 -stderr 64 -stdout 65 -stderr 65 -stdout 66 -stderr 66 -stdout 67 -stderr 67 -stdout 68 -stderr 68 -stdout 69 -stderr 69 -stdout 70 -stderr 70 -stdout 71 -stderr 71 -stdout 72 -stderr 72 -stdout 73 -stderr 73 -stdout 74 -stderr 74 -stdout 75 -stderr 75 -stdout 76 -stderr 76 -stdout 77 -stderr 77 -stdout 78 -stderr 78 -stdout 79 -stderr 79 -stdout 80 -stderr 80 -stdout 81 -stderr 81 -stdout 82 -stderr 82 -stdout 83 -stderr 83 -stdout 84 -stderr 84 -stdout 85 -stderr 85 -stdout 86 -stderr 86 -stdout 87 -stderr 87 -stdout 88 -stderr 88 -stdout 89 -stderr 89 -stdout 90 -stderr 90 -stdout 91 -stderr 91 -stdout 92 -stderr 92 -stdout 93 -stderr 93 -stdout 94 -stderr 94 -stdout 95 -stderr 95 -stdout 96 -stderr 96 -stdout 97 -stderr 97 -stdout 98 -stderr 98 -stdout 99 -stderr 99 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt deleted file mode 100644 index 5d9cac25..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/100-stdout.txt +++ /dev/null @@ -1,100 +0,0 @@ -stdout 0 -stdout 1 -stdout 2 -stdout 3 -stdout 4 -stdout 5 -stdout 6 -stdout 7 -stdout 8 -stdout 9 -stdout 10 -stdout 11 -stdout 12 -stdout 13 -stdout 14 -stdout 15 -stdout 16 -stdout 17 -stdout 18 -stdout 19 -stdout 20 -stdout 21 -stdout 22 -stdout 23 -stdout 24 -stdout 25 -stdout 26 -stdout 27 -stdout 28 -stdout 29 -stdout 30 -stdout 31 -stdout 32 -stdout 33 -stdout 34 -stdout 35 -stdout 36 -stdout 37 -stdout 38 -stdout 39 -stdout 40 -stdout 41 -stdout 42 -stdout 43 -stdout 44 -stdout 45 -stdout 46 -stdout 47 -stdout 48 -stdout 49 -stdout 50 -stdout 51 -stdout 52 -stdout 53 -stdout 54 -stdout 55 -stdout 56 -stdout 57 -stdout 58 -stdout 59 -stdout 60 -stdout 61 -stdout 62 -stdout 63 -stdout 64 -stdout 65 -stdout 66 -stdout 67 -stdout 68 -stdout 69 -stdout 70 -stdout 71 -stdout 72 -stdout 73 -stdout 74 -stdout 75 -stdout 76 -stdout 77 -stdout 78 -stdout 79 -stdout 80 -stdout 81 -stdout 82 -stdout 83 -stdout 84 -stdout 85 -stdout 86 -stdout 87 -stdout 88 -stdout 89 -stdout 90 -stdout 91 -stdout 92 -stdout 93 -stdout 94 -stdout 95 -stdout 96 -stdout 97 -stdout 98 -stdout 99 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt deleted file mode 100644 index d6375102..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stderr.txt +++ /dev/null @@ -1,1000 +0,0 @@ -stderr 0 -stderr 1 -stderr 2 -stderr 3 -stderr 4 -stderr 5 -stderr 6 -stderr 7 -stderr 8 -stderr 9 -stderr 10 -stderr 11 -stderr 12 -stderr 13 -stderr 14 -stderr 15 -stderr 16 -stderr 17 -stderr 18 -stderr 19 -stderr 20 -stderr 21 -stderr 22 -stderr 23 -stderr 24 -stderr 25 -stderr 26 -stderr 27 -stderr 28 -stderr 29 -stderr 30 -stderr 31 -stderr 32 -stderr 33 -stderr 34 -stderr 35 -stderr 36 -stderr 37 -stderr 38 -stderr 39 -stderr 40 -stderr 41 -stderr 42 -stderr 43 -stderr 44 -stderr 45 -stderr 46 -stderr 47 -stderr 48 -stderr 49 -stderr 50 -stderr 51 -stderr 52 -stderr 53 -stderr 54 -stderr 55 -stderr 56 -stderr 57 -stderr 58 -stderr 59 -stderr 60 -stderr 61 -stderr 62 -stderr 63 -stderr 64 -stderr 65 -stderr 66 -stderr 67 -stderr 68 -stderr 69 -stderr 70 -stderr 71 -stderr 72 -stderr 73 -stderr 74 -stderr 75 -stderr 76 -stderr 77 -stderr 78 -stderr 79 -stderr 80 -stderr 81 -stderr 82 -stderr 83 -stderr 84 -stderr 85 -stderr 86 -stderr 87 -stderr 88 -stderr 89 -stderr 90 -stderr 91 -stderr 92 -stderr 93 -stderr 94 -stderr 95 -stderr 96 -stderr 97 -stderr 98 -stderr 99 -stderr 100 -stderr 101 -stderr 102 -stderr 103 -stderr 104 -stderr 105 -stderr 106 -stderr 107 -stderr 108 -stderr 109 -stderr 110 -stderr 111 -stderr 112 -stderr 113 -stderr 114 -stderr 115 -stderr 116 -stderr 117 -stderr 118 -stderr 119 -stderr 120 -stderr 121 -stderr 122 -stderr 123 -stderr 124 -stderr 125 -stderr 126 -stderr 127 -stderr 128 -stderr 129 -stderr 130 -stderr 131 -stderr 132 -stderr 133 -stderr 134 -stderr 135 -stderr 136 -stderr 137 -stderr 138 -stderr 139 -stderr 140 -stderr 141 -stderr 142 -stderr 143 -stderr 144 -stderr 145 -stderr 146 -stderr 147 -stderr 148 -stderr 149 -stderr 150 -stderr 151 -stderr 152 -stderr 153 -stderr 154 -stderr 155 -stderr 156 -stderr 157 -stderr 158 -stderr 159 -stderr 160 -stderr 161 -stderr 162 -stderr 163 -stderr 164 -stderr 165 -stderr 166 -stderr 167 -stderr 168 -stderr 169 -stderr 170 -stderr 171 -stderr 172 -stderr 173 -stderr 174 -stderr 175 -stderr 176 -stderr 177 -stderr 178 -stderr 179 -stderr 180 -stderr 181 -stderr 182 -stderr 183 -stderr 184 -stderr 185 -stderr 186 -stderr 187 -stderr 188 -stderr 189 -stderr 190 -stderr 191 -stderr 192 -stderr 193 -stderr 194 -stderr 195 -stderr 196 -stderr 197 -stderr 198 -stderr 199 -stderr 200 -stderr 201 -stderr 202 -stderr 203 -stderr 204 -stderr 205 -stderr 206 -stderr 207 -stderr 208 -stderr 209 -stderr 210 -stderr 211 -stderr 212 -stderr 213 -stderr 214 -stderr 215 -stderr 216 -stderr 217 -stderr 218 -stderr 219 -stderr 220 -stderr 221 -stderr 222 -stderr 223 -stderr 224 -stderr 225 -stderr 226 -stderr 227 -stderr 228 -stderr 229 -stderr 230 -stderr 231 -stderr 232 -stderr 233 -stderr 234 -stderr 235 -stderr 236 -stderr 237 -stderr 238 -stderr 239 -stderr 240 -stderr 241 -stderr 242 -stderr 243 -stderr 244 -stderr 245 -stderr 246 -stderr 247 -stderr 248 -stderr 249 -stderr 250 -stderr 251 -stderr 252 -stderr 253 -stderr 254 -stderr 255 -stderr 256 -stderr 257 -stderr 258 -stderr 259 -stderr 260 -stderr 261 -stderr 262 -stderr 263 -stderr 264 -stderr 265 -stderr 266 -stderr 267 -stderr 268 -stderr 269 -stderr 270 -stderr 271 -stderr 272 -stderr 273 -stderr 274 -stderr 275 -stderr 276 -stderr 277 -stderr 278 -stderr 279 -stderr 280 -stderr 281 -stderr 282 -stderr 283 -stderr 284 -stderr 285 -stderr 286 -stderr 287 -stderr 288 -stderr 289 -stderr 290 -stderr 291 -stderr 292 -stderr 293 -stderr 294 -stderr 295 -stderr 296 -stderr 297 -stderr 298 -stderr 299 -stderr 300 -stderr 301 -stderr 302 -stderr 303 -stderr 304 -stderr 305 -stderr 306 -stderr 307 -stderr 308 -stderr 309 -stderr 310 -stderr 311 -stderr 312 -stderr 313 -stderr 314 -stderr 315 -stderr 316 -stderr 317 -stderr 318 -stderr 319 -stderr 320 -stderr 321 -stderr 322 -stderr 323 -stderr 324 -stderr 325 -stderr 326 -stderr 327 -stderr 328 -stderr 329 -stderr 330 -stderr 331 -stderr 332 -stderr 333 -stderr 334 -stderr 335 -stderr 336 -stderr 337 -stderr 338 -stderr 339 -stderr 340 -stderr 341 -stderr 342 -stderr 343 -stderr 344 -stderr 345 -stderr 346 -stderr 347 -stderr 348 -stderr 349 -stderr 350 -stderr 351 -stderr 352 -stderr 353 -stderr 354 -stderr 355 -stderr 356 -stderr 357 -stderr 358 -stderr 359 -stderr 360 -stderr 361 -stderr 362 -stderr 363 -stderr 364 -stderr 365 -stderr 366 -stderr 367 -stderr 368 -stderr 369 -stderr 370 -stderr 371 -stderr 372 -stderr 373 -stderr 374 -stderr 375 -stderr 376 -stderr 377 -stderr 378 -stderr 379 -stderr 380 -stderr 381 -stderr 382 -stderr 383 -stderr 384 -stderr 385 -stderr 386 -stderr 387 -stderr 388 -stderr 389 -stderr 390 -stderr 391 -stderr 392 -stderr 393 -stderr 394 -stderr 395 -stderr 396 -stderr 397 -stderr 398 -stderr 399 -stderr 400 -stderr 401 -stderr 402 -stderr 403 -stderr 404 -stderr 405 -stderr 406 -stderr 407 -stderr 408 -stderr 409 -stderr 410 -stderr 411 -stderr 412 -stderr 413 -stderr 414 -stderr 415 -stderr 416 -stderr 417 -stderr 418 -stderr 419 -stderr 420 -stderr 421 -stderr 422 -stderr 423 -stderr 424 -stderr 425 -stderr 426 -stderr 427 -stderr 428 -stderr 429 -stderr 430 -stderr 431 -stderr 432 -stderr 433 -stderr 434 -stderr 435 -stderr 436 -stderr 437 -stderr 438 -stderr 439 -stderr 440 -stderr 441 -stderr 442 -stderr 443 -stderr 444 -stderr 445 -stderr 446 -stderr 447 -stderr 448 -stderr 449 -stderr 450 -stderr 451 -stderr 452 -stderr 453 -stderr 454 -stderr 455 -stderr 456 -stderr 457 -stderr 458 -stderr 459 -stderr 460 -stderr 461 -stderr 462 -stderr 463 -stderr 464 -stderr 465 -stderr 466 -stderr 467 -stderr 468 -stderr 469 -stderr 470 -stderr 471 -stderr 472 -stderr 473 -stderr 474 -stderr 475 -stderr 476 -stderr 477 -stderr 478 -stderr 479 -stderr 480 -stderr 481 -stderr 482 -stderr 483 -stderr 484 -stderr 485 -stderr 486 -stderr 487 -stderr 488 -stderr 489 -stderr 490 -stderr 491 -stderr 492 -stderr 493 -stderr 494 -stderr 495 -stderr 496 -stderr 497 -stderr 498 -stderr 499 -stderr 500 -stderr 501 -stderr 502 -stderr 503 -stderr 504 -stderr 505 -stderr 506 -stderr 507 -stderr 508 -stderr 509 -stderr 510 -stderr 511 -stderr 512 -stderr 513 -stderr 514 -stderr 515 -stderr 516 -stderr 517 -stderr 518 -stderr 519 -stderr 520 -stderr 521 -stderr 522 -stderr 523 -stderr 524 -stderr 525 -stderr 526 -stderr 527 -stderr 528 -stderr 529 -stderr 530 -stderr 531 -stderr 532 -stderr 533 -stderr 534 -stderr 535 -stderr 536 -stderr 537 -stderr 538 -stderr 539 -stderr 540 -stderr 541 -stderr 542 -stderr 543 -stderr 544 -stderr 545 -stderr 546 -stderr 547 -stderr 548 -stderr 549 -stderr 550 -stderr 551 -stderr 552 -stderr 553 -stderr 554 -stderr 555 -stderr 556 -stderr 557 -stderr 558 -stderr 559 -stderr 560 -stderr 561 -stderr 562 -stderr 563 -stderr 564 -stderr 565 -stderr 566 -stderr 567 -stderr 568 -stderr 569 -stderr 570 -stderr 571 -stderr 572 -stderr 573 -stderr 574 -stderr 575 -stderr 576 -stderr 577 -stderr 578 -stderr 579 -stderr 580 -stderr 581 -stderr 582 -stderr 583 -stderr 584 -stderr 585 -stderr 586 -stderr 587 -stderr 588 -stderr 589 -stderr 590 -stderr 591 -stderr 592 -stderr 593 -stderr 594 -stderr 595 -stderr 596 -stderr 597 -stderr 598 -stderr 599 -stderr 600 -stderr 601 -stderr 602 -stderr 603 -stderr 604 -stderr 605 -stderr 606 -stderr 607 -stderr 608 -stderr 609 -stderr 610 -stderr 611 -stderr 612 -stderr 613 -stderr 614 -stderr 615 -stderr 616 -stderr 617 -stderr 618 -stderr 619 -stderr 620 -stderr 621 -stderr 622 -stderr 623 -stderr 624 -stderr 625 -stderr 626 -stderr 627 -stderr 628 -stderr 629 -stderr 630 -stderr 631 -stderr 632 -stderr 633 -stderr 634 -stderr 635 -stderr 636 -stderr 637 -stderr 638 -stderr 639 -stderr 640 -stderr 641 -stderr 642 -stderr 643 -stderr 644 -stderr 645 -stderr 646 -stderr 647 -stderr 648 -stderr 649 -stderr 650 -stderr 651 -stderr 652 -stderr 653 -stderr 654 -stderr 655 -stderr 656 -stderr 657 -stderr 658 -stderr 659 -stderr 660 -stderr 661 -stderr 662 -stderr 663 -stderr 664 -stderr 665 -stderr 666 -stderr 667 -stderr 668 -stderr 669 -stderr 670 -stderr 671 -stderr 672 -stderr 673 -stderr 674 -stderr 675 -stderr 676 -stderr 677 -stderr 678 -stderr 679 -stderr 680 -stderr 681 -stderr 682 -stderr 683 -stderr 684 -stderr 685 -stderr 686 -stderr 687 -stderr 688 -stderr 689 -stderr 690 -stderr 691 -stderr 692 -stderr 693 -stderr 694 -stderr 695 -stderr 696 -stderr 697 -stderr 698 -stderr 699 -stderr 700 -stderr 701 -stderr 702 -stderr 703 -stderr 704 -stderr 705 -stderr 706 -stderr 707 -stderr 708 -stderr 709 -stderr 710 -stderr 711 -stderr 712 -stderr 713 -stderr 714 -stderr 715 -stderr 716 -stderr 717 -stderr 718 -stderr 719 -stderr 720 -stderr 721 -stderr 722 -stderr 723 -stderr 724 -stderr 725 -stderr 726 -stderr 727 -stderr 728 -stderr 729 -stderr 730 -stderr 731 -stderr 732 -stderr 733 -stderr 734 -stderr 735 -stderr 736 -stderr 737 -stderr 738 -stderr 739 -stderr 740 -stderr 741 -stderr 742 -stderr 743 -stderr 744 -stderr 745 -stderr 746 -stderr 747 -stderr 748 -stderr 749 -stderr 750 -stderr 751 -stderr 752 -stderr 753 -stderr 754 -stderr 755 -stderr 756 -stderr 757 -stderr 758 -stderr 759 -stderr 760 -stderr 761 -stderr 762 -stderr 763 -stderr 764 -stderr 765 -stderr 766 -stderr 767 -stderr 768 -stderr 769 -stderr 770 -stderr 771 -stderr 772 -stderr 773 -stderr 774 -stderr 775 -stderr 776 -stderr 777 -stderr 778 -stderr 779 -stderr 780 -stderr 781 -stderr 782 -stderr 783 -stderr 784 -stderr 785 -stderr 786 -stderr 787 -stderr 788 -stderr 789 -stderr 790 -stderr 791 -stderr 792 -stderr 793 -stderr 794 -stderr 795 -stderr 796 -stderr 797 -stderr 798 -stderr 799 -stderr 800 -stderr 801 -stderr 802 -stderr 803 -stderr 804 -stderr 805 -stderr 806 -stderr 807 -stderr 808 -stderr 809 -stderr 810 -stderr 811 -stderr 812 -stderr 813 -stderr 814 -stderr 815 -stderr 816 -stderr 817 -stderr 818 -stderr 819 -stderr 820 -stderr 821 -stderr 822 -stderr 823 -stderr 824 -stderr 825 -stderr 826 -stderr 827 -stderr 828 -stderr 829 -stderr 830 -stderr 831 -stderr 832 -stderr 833 -stderr 834 -stderr 835 -stderr 836 -stderr 837 -stderr 838 -stderr 839 -stderr 840 -stderr 841 -stderr 842 -stderr 843 -stderr 844 -stderr 845 -stderr 846 -stderr 847 -stderr 848 -stderr 849 -stderr 850 -stderr 851 -stderr 852 -stderr 853 -stderr 854 -stderr 855 -stderr 856 -stderr 857 -stderr 858 -stderr 859 -stderr 860 -stderr 861 -stderr 862 -stderr 863 -stderr 864 -stderr 865 -stderr 866 -stderr 867 -stderr 868 -stderr 869 -stderr 870 -stderr 871 -stderr 872 -stderr 873 -stderr 874 -stderr 875 -stderr 876 -stderr 877 -stderr 878 -stderr 879 -stderr 880 -stderr 881 -stderr 882 -stderr 883 -stderr 884 -stderr 885 -stderr 886 -stderr 887 -stderr 888 -stderr 889 -stderr 890 -stderr 891 -stderr 892 -stderr 893 -stderr 894 -stderr 895 -stderr 896 -stderr 897 -stderr 898 -stderr 899 -stderr 900 -stderr 901 -stderr 902 -stderr 903 -stderr 904 -stderr 905 -stderr 906 -stderr 907 -stderr 908 -stderr 909 -stderr 910 -stderr 911 -stderr 912 -stderr 913 -stderr 914 -stderr 915 -stderr 916 -stderr 917 -stderr 918 -stderr 919 -stderr 920 -stderr 921 -stderr 922 -stderr 923 -stderr 924 -stderr 925 -stderr 926 -stderr 927 -stderr 928 -stderr 929 -stderr 930 -stderr 931 -stderr 932 -stderr 933 -stderr 934 -stderr 935 -stderr 936 -stderr 937 -stderr 938 -stderr 939 -stderr 940 -stderr 941 -stderr 942 -stderr 943 -stderr 944 -stderr 945 -stderr 946 -stderr 947 -stderr 948 -stderr 949 -stderr 950 -stderr 951 -stderr 952 -stderr 953 -stderr 954 -stderr 955 -stderr 956 -stderr 957 -stderr 958 -stderr 959 -stderr 960 -stderr 961 -stderr 962 -stderr 963 -stderr 964 -stderr 965 -stderr 966 -stderr 967 -stderr 968 -stderr 969 -stderr 970 -stderr 971 -stderr 972 -stderr 973 -stderr 974 -stderr 975 -stderr 976 -stderr 977 -stderr 978 -stderr 979 -stderr 980 -stderr 981 -stderr 982 -stderr 983 -stderr 984 -stderr 985 -stderr 986 -stderr 987 -stderr 988 -stderr 989 -stderr 990 -stderr 991 -stderr 992 -stderr 993 -stderr 994 -stderr 995 -stderr 996 -stderr 997 -stderr 998 -stderr 999 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt deleted file mode 100644 index 4fde2b4d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout-stderr.txt +++ /dev/null @@ -1,2000 +0,0 @@ -stdout 0 -stderr 0 -stdout 1 -stderr 1 -stdout 2 -stderr 2 -stdout 3 -stderr 3 -stdout 4 -stderr 4 -stdout 5 -stderr 5 -stdout 6 -stderr 6 -stdout 7 -stderr 7 -stdout 8 -stderr 8 -stdout 9 -stderr 9 -stdout 10 -stderr 10 -stdout 11 -stderr 11 -stdout 12 -stderr 12 -stdout 13 -stderr 13 -stdout 14 -stderr 14 -stdout 15 -stderr 15 -stdout 16 -stderr 16 -stdout 17 -stderr 17 -stdout 18 -stderr 18 -stdout 19 -stderr 19 -stdout 20 -stderr 20 -stdout 21 -stderr 21 -stdout 22 -stderr 22 -stdout 23 -stderr 23 -stdout 24 -stderr 24 -stdout 25 -stderr 25 -stdout 26 -stderr 26 -stdout 27 -stderr 27 -stdout 28 -stderr 28 -stdout 29 -stderr 29 -stdout 30 -stderr 30 -stdout 31 -stderr 31 -stdout 32 -stderr 32 -stdout 33 -stderr 33 -stdout 34 -stderr 34 -stdout 35 -stderr 35 -stdout 36 -stderr 36 -stdout 37 -stderr 37 -stdout 38 -stderr 38 -stdout 39 -stderr 39 -stdout 40 -stderr 40 -stdout 41 -stderr 41 -stdout 42 -stderr 42 -stdout 43 -stderr 43 -stdout 44 -stderr 44 -stdout 45 -stderr 45 -stdout 46 -stderr 46 -stdout 47 -stderr 47 -stdout 48 -stderr 48 -stdout 49 -stderr 49 -stdout 50 -stderr 50 -stdout 51 -stderr 51 -stdout 52 -stderr 52 -stdout 53 -stderr 53 -stdout 54 -stderr 54 -stdout 55 -stderr 55 -stdout 56 -stderr 56 -stdout 57 -stderr 57 -stdout 58 -stderr 58 -stdout 59 -stderr 59 -stdout 60 -stderr 60 -stdout 61 -stderr 61 -stdout 62 -stderr 62 -stdout 63 -stderr 63 -stdout 64 -stderr 64 -stdout 65 -stderr 65 -stdout 66 -stderr 66 -stdout 67 -stderr 67 -stdout 68 -stderr 68 -stdout 69 -stderr 69 -stdout 70 -stderr 70 -stdout 71 -stderr 71 -stdout 72 -stderr 72 -stdout 73 -stderr 73 -stdout 74 -stderr 74 -stdout 75 -stderr 75 -stdout 76 -stderr 76 -stdout 77 -stderr 77 -stdout 78 -stderr 78 -stdout 79 -stderr 79 -stdout 80 -stderr 80 -stdout 81 -stderr 81 -stdout 82 -stderr 82 -stdout 83 -stderr 83 -stdout 84 -stderr 84 -stdout 85 -stderr 85 -stdout 86 -stderr 86 -stdout 87 -stderr 87 -stdout 88 -stderr 88 -stdout 89 -stderr 89 -stdout 90 -stderr 90 -stdout 91 -stderr 91 -stdout 92 -stderr 92 -stdout 93 -stderr 93 -stdout 94 -stderr 94 -stdout 95 -stderr 95 -stdout 96 -stderr 96 -stdout 97 -stderr 97 -stdout 98 -stderr 98 -stdout 99 -stderr 99 -stdout 100 -stderr 100 -stdout 101 -stderr 101 -stdout 102 -stderr 102 -stdout 103 -stderr 103 -stdout 104 -stderr 104 -stdout 105 -stderr 105 -stdout 106 -stderr 106 -stdout 107 -stderr 107 -stdout 108 -stderr 108 -stdout 109 -stderr 109 -stdout 110 -stderr 110 -stdout 111 -stderr 111 -stdout 112 -stderr 112 -stdout 113 -stderr 113 -stdout 114 -stderr 114 -stdout 115 -stderr 115 -stdout 116 -stderr 116 -stdout 117 -stderr 117 -stdout 118 -stderr 118 -stdout 119 -stderr 119 -stdout 120 -stderr 120 -stdout 121 -stderr 121 -stdout 122 -stderr 122 -stdout 123 -stderr 123 -stdout 124 -stderr 124 -stdout 125 -stderr 125 -stdout 126 -stderr 126 -stdout 127 -stderr 127 -stdout 128 -stderr 128 -stdout 129 -stderr 129 -stdout 130 -stderr 130 -stdout 131 -stderr 131 -stdout 132 -stderr 132 -stdout 133 -stderr 133 -stdout 134 -stderr 134 -stdout 135 -stderr 135 -stdout 136 -stderr 136 -stdout 137 -stderr 137 -stdout 138 -stderr 138 -stdout 139 -stderr 139 -stdout 140 -stderr 140 -stdout 141 -stderr 141 -stdout 142 -stderr 142 -stdout 143 -stderr 143 -stdout 144 -stderr 144 -stdout 145 -stderr 145 -stdout 146 -stderr 146 -stdout 147 -stderr 147 -stdout 148 -stderr 148 -stdout 149 -stderr 149 -stdout 150 -stderr 150 -stdout 151 -stderr 151 -stdout 152 -stderr 152 -stdout 153 -stderr 153 -stdout 154 -stderr 154 -stdout 155 -stderr 155 -stdout 156 -stderr 156 -stdout 157 -stderr 157 -stdout 158 -stderr 158 -stdout 159 -stderr 159 -stdout 160 -stderr 160 -stdout 161 -stderr 161 -stdout 162 -stderr 162 -stdout 163 -stderr 163 -stdout 164 -stderr 164 -stdout 165 -stderr 165 -stdout 166 -stderr 166 -stdout 167 -stderr 167 -stdout 168 -stderr 168 -stdout 169 -stderr 169 -stdout 170 -stderr 170 -stdout 171 -stderr 171 -stdout 172 -stderr 172 -stdout 173 -stderr 173 -stdout 174 -stderr 174 -stdout 175 -stderr 175 -stdout 176 -stderr 176 -stdout 177 -stderr 177 -stdout 178 -stderr 178 -stdout 179 -stderr 179 -stdout 180 -stderr 180 -stdout 181 -stderr 181 -stdout 182 -stderr 182 -stdout 183 -stderr 183 -stdout 184 -stderr 184 -stdout 185 -stderr 185 -stdout 186 -stderr 186 -stdout 187 -stderr 187 -stdout 188 -stderr 188 -stdout 189 -stderr 189 -stdout 190 -stderr 190 -stdout 191 -stderr 191 -stdout 192 -stderr 192 -stdout 193 -stderr 193 -stdout 194 -stderr 194 -stdout 195 -stderr 195 -stdout 196 -stderr 196 -stdout 197 -stderr 197 -stdout 198 -stderr 198 -stdout 199 -stderr 199 -stdout 200 -stderr 200 -stdout 201 -stderr 201 -stdout 202 -stderr 202 -stdout 203 -stderr 203 -stdout 204 -stderr 204 -stdout 205 -stderr 205 -stdout 206 -stderr 206 -stdout 207 -stderr 207 -stdout 208 -stderr 208 -stdout 209 -stderr 209 -stdout 210 -stderr 210 -stdout 211 -stderr 211 -stdout 212 -stderr 212 -stdout 213 -stderr 213 -stdout 214 -stderr 214 -stdout 215 -stderr 215 -stdout 216 -stderr 216 -stdout 217 -stderr 217 -stdout 218 -stderr 218 -stdout 219 -stderr 219 -stdout 220 -stderr 220 -stdout 221 -stderr 221 -stdout 222 -stderr 222 -stdout 223 -stderr 223 -stdout 224 -stderr 224 -stdout 225 -stderr 225 -stdout 226 -stderr 226 -stdout 227 -stderr 227 -stdout 228 -stderr 228 -stdout 229 -stderr 229 -stdout 230 -stderr 230 -stdout 231 -stderr 231 -stdout 232 -stderr 232 -stdout 233 -stderr 233 -stdout 234 -stderr 234 -stdout 235 -stderr 235 -stdout 236 -stderr 236 -stdout 237 -stderr 237 -stdout 238 -stderr 238 -stdout 239 -stderr 239 -stdout 240 -stderr 240 -stdout 241 -stderr 241 -stdout 242 -stderr 242 -stdout 243 -stderr 243 -stdout 244 -stderr 244 -stdout 245 -stderr 245 -stdout 246 -stderr 246 -stdout 247 -stderr 247 -stdout 248 -stderr 248 -stdout 249 -stderr 249 -stdout 250 -stderr 250 -stdout 251 -stderr 251 -stdout 252 -stderr 252 -stdout 253 -stderr 253 -stdout 254 -stderr 254 -stdout 255 -stderr 255 -stdout 256 -stderr 256 -stdout 257 -stderr 257 -stdout 258 -stderr 258 -stdout 259 -stderr 259 -stdout 260 -stderr 260 -stdout 261 -stderr 261 -stdout 262 -stderr 262 -stdout 263 -stderr 263 -stdout 264 -stderr 264 -stdout 265 -stderr 265 -stdout 266 -stderr 266 -stdout 267 -stderr 267 -stdout 268 -stderr 268 -stdout 269 -stderr 269 -stdout 270 -stderr 270 -stdout 271 -stderr 271 -stdout 272 -stderr 272 -stdout 273 -stderr 273 -stdout 274 -stderr 274 -stdout 275 -stderr 275 -stdout 276 -stderr 276 -stdout 277 -stderr 277 -stdout 278 -stderr 278 -stdout 279 -stderr 279 -stdout 280 -stderr 280 -stdout 281 -stderr 281 -stdout 282 -stderr 282 -stdout 283 -stderr 283 -stdout 284 -stderr 284 -stdout 285 -stderr 285 -stdout 286 -stderr 286 -stdout 287 -stderr 287 -stdout 288 -stderr 288 -stdout 289 -stderr 289 -stdout 290 -stderr 290 -stdout 291 -stderr 291 -stdout 292 -stderr 292 -stdout 293 -stderr 293 -stdout 294 -stderr 294 -stdout 295 -stderr 295 -stdout 296 -stderr 296 -stdout 297 -stderr 297 -stdout 298 -stderr 298 -stdout 299 -stderr 299 -stdout 300 -stderr 300 -stdout 301 -stderr 301 -stdout 302 -stderr 302 -stdout 303 -stderr 303 -stdout 304 -stderr 304 -stdout 305 -stderr 305 -stdout 306 -stderr 306 -stdout 307 -stderr 307 -stdout 308 -stderr 308 -stdout 309 -stderr 309 -stdout 310 -stderr 310 -stdout 311 -stderr 311 -stdout 312 -stderr 312 -stdout 313 -stderr 313 -stdout 314 -stderr 314 -stdout 315 -stderr 315 -stdout 316 -stderr 316 -stdout 317 -stderr 317 -stdout 318 -stderr 318 -stdout 319 -stderr 319 -stdout 320 -stderr 320 -stdout 321 -stderr 321 -stdout 322 -stderr 322 -stdout 323 -stderr 323 -stdout 324 -stderr 324 -stdout 325 -stderr 325 -stdout 326 -stderr 326 -stdout 327 -stderr 327 -stdout 328 -stderr 328 -stdout 329 -stderr 329 -stdout 330 -stderr 330 -stdout 331 -stderr 331 -stdout 332 -stderr 332 -stdout 333 -stderr 333 -stdout 334 -stderr 334 -stdout 335 -stderr 335 -stdout 336 -stderr 336 -stdout 337 -stderr 337 -stdout 338 -stderr 338 -stdout 339 -stderr 339 -stdout 340 -stderr 340 -stdout 341 -stderr 341 -stdout 342 -stderr 342 -stdout 343 -stderr 343 -stdout 344 -stderr 344 -stdout 345 -stderr 345 -stdout 346 -stderr 346 -stdout 347 -stderr 347 -stdout 348 -stderr 348 -stdout 349 -stderr 349 -stdout 350 -stderr 350 -stdout 351 -stderr 351 -stdout 352 -stderr 352 -stdout 353 -stderr 353 -stdout 354 -stderr 354 -stdout 355 -stderr 355 -stdout 356 -stderr 356 -stdout 357 -stderr 357 -stdout 358 -stderr 358 -stdout 359 -stderr 359 -stdout 360 -stderr 360 -stdout 361 -stderr 361 -stdout 362 -stderr 362 -stdout 363 -stderr 363 -stdout 364 -stderr 364 -stdout 365 -stderr 365 -stdout 366 -stderr 366 -stdout 367 -stderr 367 -stdout 368 -stderr 368 -stdout 369 -stderr 369 -stdout 370 -stderr 370 -stdout 371 -stderr 371 -stdout 372 -stderr 372 -stdout 373 -stderr 373 -stdout 374 -stderr 374 -stdout 375 -stderr 375 -stdout 376 -stderr 376 -stdout 377 -stderr 377 -stdout 378 -stderr 378 -stdout 379 -stderr 379 -stdout 380 -stderr 380 -stdout 381 -stderr 381 -stdout 382 -stderr 382 -stdout 383 -stderr 383 -stdout 384 -stderr 384 -stdout 385 -stderr 385 -stdout 386 -stderr 386 -stdout 387 -stderr 387 -stdout 388 -stderr 388 -stdout 389 -stderr 389 -stdout 390 -stderr 390 -stdout 391 -stderr 391 -stdout 392 -stderr 392 -stdout 393 -stderr 393 -stdout 394 -stderr 394 -stdout 395 -stderr 395 -stdout 396 -stderr 396 -stdout 397 -stderr 397 -stdout 398 -stderr 398 -stdout 399 -stderr 399 -stdout 400 -stderr 400 -stdout 401 -stderr 401 -stdout 402 -stderr 402 -stdout 403 -stderr 403 -stdout 404 -stderr 404 -stdout 405 -stderr 405 -stdout 406 -stderr 406 -stdout 407 -stderr 407 -stdout 408 -stderr 408 -stdout 409 -stderr 409 -stdout 410 -stderr 410 -stdout 411 -stderr 411 -stdout 412 -stderr 412 -stdout 413 -stderr 413 -stdout 414 -stderr 414 -stdout 415 -stderr 415 -stdout 416 -stderr 416 -stdout 417 -stderr 417 -stdout 418 -stderr 418 -stdout 419 -stderr 419 -stdout 420 -stderr 420 -stdout 421 -stderr 421 -stdout 422 -stderr 422 -stdout 423 -stderr 423 -stdout 424 -stderr 424 -stdout 425 -stderr 425 -stdout 426 -stderr 426 -stdout 427 -stderr 427 -stdout 428 -stderr 428 -stdout 429 -stderr 429 -stdout 430 -stderr 430 -stdout 431 -stderr 431 -stdout 432 -stderr 432 -stdout 433 -stderr 433 -stdout 434 -stderr 434 -stdout 435 -stderr 435 -stdout 436 -stderr 436 -stdout 437 -stderr 437 -stdout 438 -stderr 438 -stdout 439 -stderr 439 -stdout 440 -stderr 440 -stdout 441 -stderr 441 -stdout 442 -stderr 442 -stdout 443 -stderr 443 -stdout 444 -stderr 444 -stdout 445 -stderr 445 -stdout 446 -stderr 446 -stdout 447 -stderr 447 -stdout 448 -stderr 448 -stdout 449 -stderr 449 -stdout 450 -stderr 450 -stdout 451 -stderr 451 -stdout 452 -stderr 452 -stdout 453 -stderr 453 -stdout 454 -stderr 454 -stdout 455 -stderr 455 -stdout 456 -stderr 456 -stdout 457 -stderr 457 -stdout 458 -stderr 458 -stdout 459 -stderr 459 -stdout 460 -stderr 460 -stdout 461 -stderr 461 -stdout 462 -stderr 462 -stdout 463 -stderr 463 -stdout 464 -stderr 464 -stdout 465 -stderr 465 -stdout 466 -stderr 466 -stdout 467 -stderr 467 -stdout 468 -stderr 468 -stdout 469 -stderr 469 -stdout 470 -stderr 470 -stdout 471 -stderr 471 -stdout 472 -stderr 472 -stdout 473 -stderr 473 -stdout 474 -stderr 474 -stdout 475 -stderr 475 -stdout 476 -stderr 476 -stdout 477 -stderr 477 -stdout 478 -stderr 478 -stdout 479 -stderr 479 -stdout 480 -stderr 480 -stdout 481 -stderr 481 -stdout 482 -stderr 482 -stdout 483 -stderr 483 -stdout 484 -stderr 484 -stdout 485 -stderr 485 -stdout 486 -stderr 486 -stdout 487 -stderr 487 -stdout 488 -stderr 488 -stdout 489 -stderr 489 -stdout 490 -stderr 490 -stdout 491 -stderr 491 -stdout 492 -stderr 492 -stdout 493 -stderr 493 -stdout 494 -stderr 494 -stdout 495 -stderr 495 -stdout 496 -stderr 496 -stdout 497 -stderr 497 -stdout 498 -stderr 498 -stdout 499 -stderr 499 -stdout 500 -stderr 500 -stdout 501 -stderr 501 -stdout 502 -stderr 502 -stdout 503 -stderr 503 -stdout 504 -stderr 504 -stdout 505 -stderr 505 -stdout 506 -stderr 506 -stdout 507 -stderr 507 -stdout 508 -stderr 508 -stdout 509 -stderr 509 -stdout 510 -stderr 510 -stdout 511 -stderr 511 -stdout 512 -stderr 512 -stdout 513 -stderr 513 -stdout 514 -stderr 514 -stdout 515 -stderr 515 -stdout 516 -stderr 516 -stdout 517 -stderr 517 -stdout 518 -stderr 518 -stdout 519 -stderr 519 -stdout 520 -stderr 520 -stdout 521 -stderr 521 -stdout 522 -stderr 522 -stdout 523 -stderr 523 -stdout 524 -stderr 524 -stdout 525 -stderr 525 -stdout 526 -stderr 526 -stdout 527 -stderr 527 -stdout 528 -stderr 528 -stdout 529 -stderr 529 -stdout 530 -stderr 530 -stdout 531 -stderr 531 -stdout 532 -stderr 532 -stdout 533 -stderr 533 -stdout 534 -stderr 534 -stdout 535 -stderr 535 -stdout 536 -stderr 536 -stdout 537 -stderr 537 -stdout 538 -stderr 538 -stdout 539 -stderr 539 -stdout 540 -stderr 540 -stdout 541 -stderr 541 -stdout 542 -stderr 542 -stdout 543 -stderr 543 -stdout 544 -stderr 544 -stdout 545 -stderr 545 -stdout 546 -stderr 546 -stdout 547 -stderr 547 -stdout 548 -stderr 548 -stdout 549 -stderr 549 -stdout 550 -stderr 550 -stdout 551 -stderr 551 -stdout 552 -stderr 552 -stdout 553 -stderr 553 -stdout 554 -stderr 554 -stdout 555 -stderr 555 -stdout 556 -stderr 556 -stdout 557 -stderr 557 -stdout 558 -stderr 558 -stdout 559 -stderr 559 -stdout 560 -stderr 560 -stdout 561 -stderr 561 -stdout 562 -stderr 562 -stdout 563 -stderr 563 -stdout 564 -stderr 564 -stdout 565 -stderr 565 -stdout 566 -stderr 566 -stdout 567 -stderr 567 -stdout 568 -stderr 568 -stdout 569 -stderr 569 -stdout 570 -stderr 570 -stdout 571 -stderr 571 -stdout 572 -stderr 572 -stdout 573 -stderr 573 -stdout 574 -stderr 574 -stdout 575 -stderr 575 -stdout 576 -stderr 576 -stdout 577 -stderr 577 -stdout 578 -stderr 578 -stdout 579 -stderr 579 -stdout 580 -stderr 580 -stdout 581 -stderr 581 -stdout 582 -stderr 582 -stdout 583 -stderr 583 -stdout 584 -stderr 584 -stdout 585 -stderr 585 -stdout 586 -stderr 586 -stdout 587 -stderr 587 -stdout 588 -stderr 588 -stdout 589 -stderr 589 -stdout 590 -stderr 590 -stdout 591 -stderr 591 -stdout 592 -stderr 592 -stdout 593 -stderr 593 -stdout 594 -stderr 594 -stdout 595 -stderr 595 -stdout 596 -stderr 596 -stdout 597 -stderr 597 -stdout 598 -stderr 598 -stdout 599 -stderr 599 -stdout 600 -stderr 600 -stdout 601 -stderr 601 -stdout 602 -stderr 602 -stdout 603 -stderr 603 -stdout 604 -stderr 604 -stdout 605 -stderr 605 -stdout 606 -stderr 606 -stdout 607 -stderr 607 -stdout 608 -stderr 608 -stdout 609 -stderr 609 -stdout 610 -stderr 610 -stdout 611 -stderr 611 -stdout 612 -stderr 612 -stdout 613 -stderr 613 -stdout 614 -stderr 614 -stdout 615 -stderr 615 -stdout 616 -stderr 616 -stdout 617 -stderr 617 -stdout 618 -stderr 618 -stdout 619 -stderr 619 -stdout 620 -stderr 620 -stdout 621 -stderr 621 -stdout 622 -stderr 622 -stdout 623 -stderr 623 -stdout 624 -stderr 624 -stdout 625 -stderr 625 -stdout 626 -stderr 626 -stdout 627 -stderr 627 -stdout 628 -stderr 628 -stdout 629 -stderr 629 -stdout 630 -stderr 630 -stdout 631 -stderr 631 -stdout 632 -stderr 632 -stdout 633 -stderr 633 -stdout 634 -stderr 634 -stdout 635 -stderr 635 -stdout 636 -stderr 636 -stdout 637 -stderr 637 -stdout 638 -stderr 638 -stdout 639 -stderr 639 -stdout 640 -stderr 640 -stdout 641 -stderr 641 -stdout 642 -stderr 642 -stdout 643 -stderr 643 -stdout 644 -stderr 644 -stdout 645 -stderr 645 -stdout 646 -stderr 646 -stdout 647 -stderr 647 -stdout 648 -stderr 648 -stdout 649 -stderr 649 -stdout 650 -stderr 650 -stdout 651 -stderr 651 -stdout 652 -stderr 652 -stdout 653 -stderr 653 -stdout 654 -stderr 654 -stdout 655 -stderr 655 -stdout 656 -stderr 656 -stdout 657 -stderr 657 -stdout 658 -stderr 658 -stdout 659 -stderr 659 -stdout 660 -stderr 660 -stdout 661 -stderr 661 -stdout 662 -stderr 662 -stdout 663 -stderr 663 -stdout 664 -stderr 664 -stdout 665 -stderr 665 -stdout 666 -stderr 666 -stdout 667 -stderr 667 -stdout 668 -stderr 668 -stdout 669 -stderr 669 -stdout 670 -stderr 670 -stdout 671 -stderr 671 -stdout 672 -stderr 672 -stdout 673 -stderr 673 -stdout 674 -stderr 674 -stdout 675 -stderr 675 -stdout 676 -stderr 676 -stdout 677 -stderr 677 -stdout 678 -stderr 678 -stdout 679 -stderr 679 -stdout 680 -stderr 680 -stdout 681 -stderr 681 -stdout 682 -stderr 682 -stdout 683 -stderr 683 -stdout 684 -stderr 684 -stdout 685 -stderr 685 -stdout 686 -stderr 686 -stdout 687 -stderr 687 -stdout 688 -stderr 688 -stdout 689 -stderr 689 -stdout 690 -stderr 690 -stdout 691 -stderr 691 -stdout 692 -stderr 692 -stdout 693 -stderr 693 -stdout 694 -stderr 694 -stdout 695 -stderr 695 -stdout 696 -stderr 696 -stdout 697 -stderr 697 -stdout 698 -stderr 698 -stdout 699 -stderr 699 -stdout 700 -stderr 700 -stdout 701 -stderr 701 -stdout 702 -stderr 702 -stdout 703 -stderr 703 -stdout 704 -stderr 704 -stdout 705 -stderr 705 -stdout 706 -stderr 706 -stdout 707 -stderr 707 -stdout 708 -stderr 708 -stdout 709 -stderr 709 -stdout 710 -stderr 710 -stdout 711 -stderr 711 -stdout 712 -stderr 712 -stdout 713 -stderr 713 -stdout 714 -stderr 714 -stdout 715 -stderr 715 -stdout 716 -stderr 716 -stdout 717 -stderr 717 -stdout 718 -stderr 718 -stdout 719 -stderr 719 -stdout 720 -stderr 720 -stdout 721 -stderr 721 -stdout 722 -stderr 722 -stdout 723 -stderr 723 -stdout 724 -stderr 724 -stdout 725 -stderr 725 -stdout 726 -stderr 726 -stdout 727 -stderr 727 -stdout 728 -stderr 728 -stdout 729 -stderr 729 -stdout 730 -stderr 730 -stdout 731 -stderr 731 -stdout 732 -stderr 732 -stdout 733 -stderr 733 -stdout 734 -stderr 734 -stdout 735 -stderr 735 -stdout 736 -stderr 736 -stdout 737 -stderr 737 -stdout 738 -stderr 738 -stdout 739 -stderr 739 -stdout 740 -stderr 740 -stdout 741 -stderr 741 -stdout 742 -stderr 742 -stdout 743 -stderr 743 -stdout 744 -stderr 744 -stdout 745 -stderr 745 -stdout 746 -stderr 746 -stdout 747 -stderr 747 -stdout 748 -stderr 748 -stdout 749 -stderr 749 -stdout 750 -stderr 750 -stdout 751 -stderr 751 -stdout 752 -stderr 752 -stdout 753 -stderr 753 -stdout 754 -stderr 754 -stdout 755 -stderr 755 -stdout 756 -stderr 756 -stdout 757 -stderr 757 -stdout 758 -stderr 758 -stdout 759 -stderr 759 -stdout 760 -stderr 760 -stdout 761 -stderr 761 -stdout 762 -stderr 762 -stdout 763 -stderr 763 -stdout 764 -stderr 764 -stdout 765 -stderr 765 -stdout 766 -stderr 766 -stdout 767 -stderr 767 -stdout 768 -stderr 768 -stdout 769 -stderr 769 -stdout 770 -stderr 770 -stdout 771 -stderr 771 -stdout 772 -stderr 772 -stdout 773 -stderr 773 -stdout 774 -stderr 774 -stdout 775 -stderr 775 -stdout 776 -stderr 776 -stdout 777 -stderr 777 -stdout 778 -stderr 778 -stdout 779 -stderr 779 -stdout 780 -stderr 780 -stdout 781 -stderr 781 -stdout 782 -stderr 782 -stdout 783 -stderr 783 -stdout 784 -stderr 784 -stdout 785 -stderr 785 -stdout 786 -stderr 786 -stdout 787 -stderr 787 -stdout 788 -stderr 788 -stdout 789 -stderr 789 -stdout 790 -stderr 790 -stdout 791 -stderr 791 -stdout 792 -stderr 792 -stdout 793 -stderr 793 -stdout 794 -stderr 794 -stdout 795 -stderr 795 -stdout 796 -stderr 796 -stdout 797 -stderr 797 -stdout 798 -stderr 798 -stdout 799 -stderr 799 -stdout 800 -stderr 800 -stdout 801 -stderr 801 -stdout 802 -stderr 802 -stdout 803 -stderr 803 -stdout 804 -stderr 804 -stdout 805 -stderr 805 -stdout 806 -stderr 806 -stdout 807 -stderr 807 -stdout 808 -stderr 808 -stdout 809 -stderr 809 -stdout 810 -stderr 810 -stdout 811 -stderr 811 -stdout 812 -stderr 812 -stdout 813 -stderr 813 -stdout 814 -stderr 814 -stdout 815 -stderr 815 -stdout 816 -stderr 816 -stdout 817 -stderr 817 -stdout 818 -stderr 818 -stdout 819 -stderr 819 -stdout 820 -stderr 820 -stdout 821 -stderr 821 -stdout 822 -stderr 822 -stdout 823 -stderr 823 -stdout 824 -stderr 824 -stdout 825 -stderr 825 -stdout 826 -stderr 826 -stdout 827 -stderr 827 -stdout 828 -stderr 828 -stdout 829 -stderr 829 -stdout 830 -stderr 830 -stdout 831 -stderr 831 -stdout 832 -stderr 832 -stdout 833 -stderr 833 -stdout 834 -stderr 834 -stdout 835 -stderr 835 -stdout 836 -stderr 836 -stdout 837 -stderr 837 -stdout 838 -stderr 838 -stdout 839 -stderr 839 -stdout 840 -stderr 840 -stdout 841 -stderr 841 -stdout 842 -stderr 842 -stdout 843 -stderr 843 -stdout 844 -stderr 844 -stdout 845 -stderr 845 -stdout 846 -stderr 846 -stdout 847 -stderr 847 -stdout 848 -stderr 848 -stdout 849 -stderr 849 -stdout 850 -stderr 850 -stdout 851 -stderr 851 -stdout 852 -stderr 852 -stdout 853 -stderr 853 -stdout 854 -stderr 854 -stdout 855 -stderr 855 -stdout 856 -stderr 856 -stdout 857 -stderr 857 -stdout 858 -stderr 858 -stdout 859 -stderr 859 -stdout 860 -stderr 860 -stdout 861 -stderr 861 -stdout 862 -stderr 862 -stdout 863 -stderr 863 -stdout 864 -stderr 864 -stdout 865 -stderr 865 -stdout 866 -stderr 866 -stdout 867 -stderr 867 -stdout 868 -stderr 868 -stdout 869 -stderr 869 -stdout 870 -stderr 870 -stdout 871 -stderr 871 -stdout 872 -stderr 872 -stdout 873 -stderr 873 -stdout 874 -stderr 874 -stdout 875 -stderr 875 -stdout 876 -stderr 876 -stdout 877 -stderr 877 -stdout 878 -stderr 878 -stdout 879 -stderr 879 -stdout 880 -stderr 880 -stdout 881 -stderr 881 -stdout 882 -stderr 882 -stdout 883 -stderr 883 -stdout 884 -stderr 884 -stdout 885 -stderr 885 -stdout 886 -stderr 886 -stdout 887 -stderr 887 -stdout 888 -stderr 888 -stdout 889 -stderr 889 -stdout 890 -stderr 890 -stdout 891 -stderr 891 -stdout 892 -stderr 892 -stdout 893 -stderr 893 -stdout 894 -stderr 894 -stdout 895 -stderr 895 -stdout 896 -stderr 896 -stdout 897 -stderr 897 -stdout 898 -stderr 898 -stdout 899 -stderr 899 -stdout 900 -stderr 900 -stdout 901 -stderr 901 -stdout 902 -stderr 902 -stdout 903 -stderr 903 -stdout 904 -stderr 904 -stdout 905 -stderr 905 -stdout 906 -stderr 906 -stdout 907 -stderr 907 -stdout 908 -stderr 908 -stdout 909 -stderr 909 -stdout 910 -stderr 910 -stdout 911 -stderr 911 -stdout 912 -stderr 912 -stdout 913 -stderr 913 -stdout 914 -stderr 914 -stdout 915 -stderr 915 -stdout 916 -stderr 916 -stdout 917 -stderr 917 -stdout 918 -stderr 918 -stdout 919 -stderr 919 -stdout 920 -stderr 920 -stdout 921 -stderr 921 -stdout 922 -stderr 922 -stdout 923 -stderr 923 -stdout 924 -stderr 924 -stdout 925 -stderr 925 -stdout 926 -stderr 926 -stdout 927 -stderr 927 -stdout 928 -stderr 928 -stdout 929 -stderr 929 -stdout 930 -stderr 930 -stdout 931 -stderr 931 -stdout 932 -stderr 932 -stdout 933 -stderr 933 -stdout 934 -stderr 934 -stdout 935 -stderr 935 -stdout 936 -stderr 936 -stdout 937 -stderr 937 -stdout 938 -stderr 938 -stdout 939 -stderr 939 -stdout 940 -stderr 940 -stdout 941 -stderr 941 -stdout 942 -stderr 942 -stdout 943 -stderr 943 -stdout 944 -stderr 944 -stdout 945 -stderr 945 -stdout 946 -stderr 946 -stdout 947 -stderr 947 -stdout 948 -stderr 948 -stdout 949 -stderr 949 -stdout 950 -stderr 950 -stdout 951 -stderr 951 -stdout 952 -stderr 952 -stdout 953 -stderr 953 -stdout 954 -stderr 954 -stdout 955 -stderr 955 -stdout 956 -stderr 956 -stdout 957 -stderr 957 -stdout 958 -stderr 958 -stdout 959 -stderr 959 -stdout 960 -stderr 960 -stdout 961 -stderr 961 -stdout 962 -stderr 962 -stdout 963 -stderr 963 -stdout 964 -stderr 964 -stdout 965 -stderr 965 -stdout 966 -stderr 966 -stdout 967 -stderr 967 -stdout 968 -stderr 968 -stdout 969 -stderr 969 -stdout 970 -stderr 970 -stdout 971 -stderr 971 -stdout 972 -stderr 972 -stdout 973 -stderr 973 -stdout 974 -stderr 974 -stdout 975 -stderr 975 -stdout 976 -stderr 976 -stdout 977 -stderr 977 -stdout 978 -stderr 978 -stdout 979 -stderr 979 -stdout 980 -stderr 980 -stdout 981 -stderr 981 -stdout 982 -stderr 982 -stdout 983 -stderr 983 -stdout 984 -stderr 984 -stdout 985 -stderr 985 -stdout 986 -stderr 986 -stdout 987 -stderr 987 -stdout 988 -stderr 988 -stdout 989 -stderr 989 -stdout 990 -stderr 990 -stdout 991 -stderr 991 -stdout 992 -stderr 992 -stdout 993 -stderr 993 -stdout 994 -stderr 994 -stdout 995 -stderr 995 -stdout 996 -stderr 996 -stdout 997 -stderr 997 -stdout 998 -stderr 998 -stdout 999 -stderr 999 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt deleted file mode 100644 index d3649d00..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/1000-stdout.txt +++ /dev/null @@ -1,1000 +0,0 @@ -stdout 0 -stdout 1 -stdout 2 -stdout 3 -stdout 4 -stdout 5 -stdout 6 -stdout 7 -stdout 8 -stdout 9 -stdout 10 -stdout 11 -stdout 12 -stdout 13 -stdout 14 -stdout 15 -stdout 16 -stdout 17 -stdout 18 -stdout 19 -stdout 20 -stdout 21 -stdout 22 -stdout 23 -stdout 24 -stdout 25 -stdout 26 -stdout 27 -stdout 28 -stdout 29 -stdout 30 -stdout 31 -stdout 32 -stdout 33 -stdout 34 -stdout 35 -stdout 36 -stdout 37 -stdout 38 -stdout 39 -stdout 40 -stdout 41 -stdout 42 -stdout 43 -stdout 44 -stdout 45 -stdout 46 -stdout 47 -stdout 48 -stdout 49 -stdout 50 -stdout 51 -stdout 52 -stdout 53 -stdout 54 -stdout 55 -stdout 56 -stdout 57 -stdout 58 -stdout 59 -stdout 60 -stdout 61 -stdout 62 -stdout 63 -stdout 64 -stdout 65 -stdout 66 -stdout 67 -stdout 68 -stdout 69 -stdout 70 -stdout 71 -stdout 72 -stdout 73 -stdout 74 -stdout 75 -stdout 76 -stdout 77 -stdout 78 -stdout 79 -stdout 80 -stdout 81 -stdout 82 -stdout 83 -stdout 84 -stdout 85 -stdout 86 -stdout 87 -stdout 88 -stdout 89 -stdout 90 -stdout 91 -stdout 92 -stdout 93 -stdout 94 -stdout 95 -stdout 96 -stdout 97 -stdout 98 -stdout 99 -stdout 100 -stdout 101 -stdout 102 -stdout 103 -stdout 104 -stdout 105 -stdout 106 -stdout 107 -stdout 108 -stdout 109 -stdout 110 -stdout 111 -stdout 112 -stdout 113 -stdout 114 -stdout 115 -stdout 116 -stdout 117 -stdout 118 -stdout 119 -stdout 120 -stdout 121 -stdout 122 -stdout 123 -stdout 124 -stdout 125 -stdout 126 -stdout 127 -stdout 128 -stdout 129 -stdout 130 -stdout 131 -stdout 132 -stdout 133 -stdout 134 -stdout 135 -stdout 136 -stdout 137 -stdout 138 -stdout 139 -stdout 140 -stdout 141 -stdout 142 -stdout 143 -stdout 144 -stdout 145 -stdout 146 -stdout 147 -stdout 148 -stdout 149 -stdout 150 -stdout 151 -stdout 152 -stdout 153 -stdout 154 -stdout 155 -stdout 156 -stdout 157 -stdout 158 -stdout 159 -stdout 160 -stdout 161 -stdout 162 -stdout 163 -stdout 164 -stdout 165 -stdout 166 -stdout 167 -stdout 168 -stdout 169 -stdout 170 -stdout 171 -stdout 172 -stdout 173 -stdout 174 -stdout 175 -stdout 176 -stdout 177 -stdout 178 -stdout 179 -stdout 180 -stdout 181 -stdout 182 -stdout 183 -stdout 184 -stdout 185 -stdout 186 -stdout 187 -stdout 188 -stdout 189 -stdout 190 -stdout 191 -stdout 192 -stdout 193 -stdout 194 -stdout 195 -stdout 196 -stdout 197 -stdout 198 -stdout 199 -stdout 200 -stdout 201 -stdout 202 -stdout 203 -stdout 204 -stdout 205 -stdout 206 -stdout 207 -stdout 208 -stdout 209 -stdout 210 -stdout 211 -stdout 212 -stdout 213 -stdout 214 -stdout 215 -stdout 216 -stdout 217 -stdout 218 -stdout 219 -stdout 220 -stdout 221 -stdout 222 -stdout 223 -stdout 224 -stdout 225 -stdout 226 -stdout 227 -stdout 228 -stdout 229 -stdout 230 -stdout 231 -stdout 232 -stdout 233 -stdout 234 -stdout 235 -stdout 236 -stdout 237 -stdout 238 -stdout 239 -stdout 240 -stdout 241 -stdout 242 -stdout 243 -stdout 244 -stdout 245 -stdout 246 -stdout 247 -stdout 248 -stdout 249 -stdout 250 -stdout 251 -stdout 252 -stdout 253 -stdout 254 -stdout 255 -stdout 256 -stdout 257 -stdout 258 -stdout 259 -stdout 260 -stdout 261 -stdout 262 -stdout 263 -stdout 264 -stdout 265 -stdout 266 -stdout 267 -stdout 268 -stdout 269 -stdout 270 -stdout 271 -stdout 272 -stdout 273 -stdout 274 -stdout 275 -stdout 276 -stdout 277 -stdout 278 -stdout 279 -stdout 280 -stdout 281 -stdout 282 -stdout 283 -stdout 284 -stdout 285 -stdout 286 -stdout 287 -stdout 288 -stdout 289 -stdout 290 -stdout 291 -stdout 292 -stdout 293 -stdout 294 -stdout 295 -stdout 296 -stdout 297 -stdout 298 -stdout 299 -stdout 300 -stdout 301 -stdout 302 -stdout 303 -stdout 304 -stdout 305 -stdout 306 -stdout 307 -stdout 308 -stdout 309 -stdout 310 -stdout 311 -stdout 312 -stdout 313 -stdout 314 -stdout 315 -stdout 316 -stdout 317 -stdout 318 -stdout 319 -stdout 320 -stdout 321 -stdout 322 -stdout 323 -stdout 324 -stdout 325 -stdout 326 -stdout 327 -stdout 328 -stdout 329 -stdout 330 -stdout 331 -stdout 332 -stdout 333 -stdout 334 -stdout 335 -stdout 336 -stdout 337 -stdout 338 -stdout 339 -stdout 340 -stdout 341 -stdout 342 -stdout 343 -stdout 344 -stdout 345 -stdout 346 -stdout 347 -stdout 348 -stdout 349 -stdout 350 -stdout 351 -stdout 352 -stdout 353 -stdout 354 -stdout 355 -stdout 356 -stdout 357 -stdout 358 -stdout 359 -stdout 360 -stdout 361 -stdout 362 -stdout 363 -stdout 364 -stdout 365 -stdout 366 -stdout 367 -stdout 368 -stdout 369 -stdout 370 -stdout 371 -stdout 372 -stdout 373 -stdout 374 -stdout 375 -stdout 376 -stdout 377 -stdout 378 -stdout 379 -stdout 380 -stdout 381 -stdout 382 -stdout 383 -stdout 384 -stdout 385 -stdout 386 -stdout 387 -stdout 388 -stdout 389 -stdout 390 -stdout 391 -stdout 392 -stdout 393 -stdout 394 -stdout 395 -stdout 396 -stdout 397 -stdout 398 -stdout 399 -stdout 400 -stdout 401 -stdout 402 -stdout 403 -stdout 404 -stdout 405 -stdout 406 -stdout 407 -stdout 408 -stdout 409 -stdout 410 -stdout 411 -stdout 412 -stdout 413 -stdout 414 -stdout 415 -stdout 416 -stdout 417 -stdout 418 -stdout 419 -stdout 420 -stdout 421 -stdout 422 -stdout 423 -stdout 424 -stdout 425 -stdout 426 -stdout 427 -stdout 428 -stdout 429 -stdout 430 -stdout 431 -stdout 432 -stdout 433 -stdout 434 -stdout 435 -stdout 436 -stdout 437 -stdout 438 -stdout 439 -stdout 440 -stdout 441 -stdout 442 -stdout 443 -stdout 444 -stdout 445 -stdout 446 -stdout 447 -stdout 448 -stdout 449 -stdout 450 -stdout 451 -stdout 452 -stdout 453 -stdout 454 -stdout 455 -stdout 456 -stdout 457 -stdout 458 -stdout 459 -stdout 460 -stdout 461 -stdout 462 -stdout 463 -stdout 464 -stdout 465 -stdout 466 -stdout 467 -stdout 468 -stdout 469 -stdout 470 -stdout 471 -stdout 472 -stdout 473 -stdout 474 -stdout 475 -stdout 476 -stdout 477 -stdout 478 -stdout 479 -stdout 480 -stdout 481 -stdout 482 -stdout 483 -stdout 484 -stdout 485 -stdout 486 -stdout 487 -stdout 488 -stdout 489 -stdout 490 -stdout 491 -stdout 492 -stdout 493 -stdout 494 -stdout 495 -stdout 496 -stdout 497 -stdout 498 -stdout 499 -stdout 500 -stdout 501 -stdout 502 -stdout 503 -stdout 504 -stdout 505 -stdout 506 -stdout 507 -stdout 508 -stdout 509 -stdout 510 -stdout 511 -stdout 512 -stdout 513 -stdout 514 -stdout 515 -stdout 516 -stdout 517 -stdout 518 -stdout 519 -stdout 520 -stdout 521 -stdout 522 -stdout 523 -stdout 524 -stdout 525 -stdout 526 -stdout 527 -stdout 528 -stdout 529 -stdout 530 -stdout 531 -stdout 532 -stdout 533 -stdout 534 -stdout 535 -stdout 536 -stdout 537 -stdout 538 -stdout 539 -stdout 540 -stdout 541 -stdout 542 -stdout 543 -stdout 544 -stdout 545 -stdout 546 -stdout 547 -stdout 548 -stdout 549 -stdout 550 -stdout 551 -stdout 552 -stdout 553 -stdout 554 -stdout 555 -stdout 556 -stdout 557 -stdout 558 -stdout 559 -stdout 560 -stdout 561 -stdout 562 -stdout 563 -stdout 564 -stdout 565 -stdout 566 -stdout 567 -stdout 568 -stdout 569 -stdout 570 -stdout 571 -stdout 572 -stdout 573 -stdout 574 -stdout 575 -stdout 576 -stdout 577 -stdout 578 -stdout 579 -stdout 580 -stdout 581 -stdout 582 -stdout 583 -stdout 584 -stdout 585 -stdout 586 -stdout 587 -stdout 588 -stdout 589 -stdout 590 -stdout 591 -stdout 592 -stdout 593 -stdout 594 -stdout 595 -stdout 596 -stdout 597 -stdout 598 -stdout 599 -stdout 600 -stdout 601 -stdout 602 -stdout 603 -stdout 604 -stdout 605 -stdout 606 -stdout 607 -stdout 608 -stdout 609 -stdout 610 -stdout 611 -stdout 612 -stdout 613 -stdout 614 -stdout 615 -stdout 616 -stdout 617 -stdout 618 -stdout 619 -stdout 620 -stdout 621 -stdout 622 -stdout 623 -stdout 624 -stdout 625 -stdout 626 -stdout 627 -stdout 628 -stdout 629 -stdout 630 -stdout 631 -stdout 632 -stdout 633 -stdout 634 -stdout 635 -stdout 636 -stdout 637 -stdout 638 -stdout 639 -stdout 640 -stdout 641 -stdout 642 -stdout 643 -stdout 644 -stdout 645 -stdout 646 -stdout 647 -stdout 648 -stdout 649 -stdout 650 -stdout 651 -stdout 652 -stdout 653 -stdout 654 -stdout 655 -stdout 656 -stdout 657 -stdout 658 -stdout 659 -stdout 660 -stdout 661 -stdout 662 -stdout 663 -stdout 664 -stdout 665 -stdout 666 -stdout 667 -stdout 668 -stdout 669 -stdout 670 -stdout 671 -stdout 672 -stdout 673 -stdout 674 -stdout 675 -stdout 676 -stdout 677 -stdout 678 -stdout 679 -stdout 680 -stdout 681 -stdout 682 -stdout 683 -stdout 684 -stdout 685 -stdout 686 -stdout 687 -stdout 688 -stdout 689 -stdout 690 -stdout 691 -stdout 692 -stdout 693 -stdout 694 -stdout 695 -stdout 696 -stdout 697 -stdout 698 -stdout 699 -stdout 700 -stdout 701 -stdout 702 -stdout 703 -stdout 704 -stdout 705 -stdout 706 -stdout 707 -stdout 708 -stdout 709 -stdout 710 -stdout 711 -stdout 712 -stdout 713 -stdout 714 -stdout 715 -stdout 716 -stdout 717 -stdout 718 -stdout 719 -stdout 720 -stdout 721 -stdout 722 -stdout 723 -stdout 724 -stdout 725 -stdout 726 -stdout 727 -stdout 728 -stdout 729 -stdout 730 -stdout 731 -stdout 732 -stdout 733 -stdout 734 -stdout 735 -stdout 736 -stdout 737 -stdout 738 -stdout 739 -stdout 740 -stdout 741 -stdout 742 -stdout 743 -stdout 744 -stdout 745 -stdout 746 -stdout 747 -stdout 748 -stdout 749 -stdout 750 -stdout 751 -stdout 752 -stdout 753 -stdout 754 -stdout 755 -stdout 756 -stdout 757 -stdout 758 -stdout 759 -stdout 760 -stdout 761 -stdout 762 -stdout 763 -stdout 764 -stdout 765 -stdout 766 -stdout 767 -stdout 768 -stdout 769 -stdout 770 -stdout 771 -stdout 772 -stdout 773 -stdout 774 -stdout 775 -stdout 776 -stdout 777 -stdout 778 -stdout 779 -stdout 780 -stdout 781 -stdout 782 -stdout 783 -stdout 784 -stdout 785 -stdout 786 -stdout 787 -stdout 788 -stdout 789 -stdout 790 -stdout 791 -stdout 792 -stdout 793 -stdout 794 -stdout 795 -stdout 796 -stdout 797 -stdout 798 -stdout 799 -stdout 800 -stdout 801 -stdout 802 -stdout 803 -stdout 804 -stdout 805 -stdout 806 -stdout 807 -stdout 808 -stdout 809 -stdout 810 -stdout 811 -stdout 812 -stdout 813 -stdout 814 -stdout 815 -stdout 816 -stdout 817 -stdout 818 -stdout 819 -stdout 820 -stdout 821 -stdout 822 -stdout 823 -stdout 824 -stdout 825 -stdout 826 -stdout 827 -stdout 828 -stdout 829 -stdout 830 -stdout 831 -stdout 832 -stdout 833 -stdout 834 -stdout 835 -stdout 836 -stdout 837 -stdout 838 -stdout 839 -stdout 840 -stdout 841 -stdout 842 -stdout 843 -stdout 844 -stdout 845 -stdout 846 -stdout 847 -stdout 848 -stdout 849 -stdout 850 -stdout 851 -stdout 852 -stdout 853 -stdout 854 -stdout 855 -stdout 856 -stdout 857 -stdout 858 -stdout 859 -stdout 860 -stdout 861 -stdout 862 -stdout 863 -stdout 864 -stdout 865 -stdout 866 -stdout 867 -stdout 868 -stdout 869 -stdout 870 -stdout 871 -stdout 872 -stdout 873 -stdout 874 -stdout 875 -stdout 876 -stdout 877 -stdout 878 -stdout 879 -stdout 880 -stdout 881 -stdout 882 -stdout 883 -stdout 884 -stdout 885 -stdout 886 -stdout 887 -stdout 888 -stdout 889 -stdout 890 -stdout 891 -stdout 892 -stdout 893 -stdout 894 -stdout 895 -stdout 896 -stdout 897 -stdout 898 -stdout 899 -stdout 900 -stdout 901 -stdout 902 -stdout 903 -stdout 904 -stdout 905 -stdout 906 -stdout 907 -stdout 908 -stdout 909 -stdout 910 -stdout 911 -stdout 912 -stdout 913 -stdout 914 -stdout 915 -stdout 916 -stdout 917 -stdout 918 -stdout 919 -stdout 920 -stdout 921 -stdout 922 -stdout 923 -stdout 924 -stdout 925 -stdout 926 -stdout 927 -stdout 928 -stdout 929 -stdout 930 -stdout 931 -stdout 932 -stdout 933 -stdout 934 -stdout 935 -stdout 936 -stdout 937 -stdout 938 -stdout 939 -stdout 940 -stdout 941 -stdout 942 -stdout 943 -stdout 944 -stdout 945 -stdout 946 -stdout 947 -stdout 948 -stdout 949 -stdout 950 -stdout 951 -stdout 952 -stdout 953 -stdout 954 -stdout 955 -stdout 956 -stdout 957 -stdout 958 -stdout 959 -stdout 960 -stdout 961 -stdout 962 -stdout 963 -stdout 964 -stdout 965 -stdout 966 -stdout 967 -stdout 968 -stdout 969 -stdout 970 -stdout 971 -stdout 972 -stdout 973 -stdout 974 -stdout 975 -stdout 976 -stdout 977 -stdout 978 -stdout 979 -stdout 980 -stdout 981 -stdout 982 -stdout 983 -stdout 984 -stdout 985 -stdout 986 -stdout 987 -stdout 988 -stdout 989 -stdout 990 -stdout 991 -stdout 992 -stdout 993 -stdout 994 -stdout 995 -stdout 996 -stdout 997 -stdout 998 -stdout 999 diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh deleted file mode 100755 index 6a526de0..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/create-files.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -rm 10*.txt -for n in 10 100 1000; do - node log.js 0 $n stdout stderr &> $n-stdout-stderr.txt - node log.js 0 $n stdout &> $n-stdout.txt - node log.js 0 $n stderr &> $n-stderr.txt -done diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js deleted file mode 100644 index 74c8f120..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log-broken.js +++ /dev/null @@ -1,23 +0,0 @@ -var errorCode = process.argv[2]; -var max = process.argv[3]; -var modes = process.argv.slice(4); - -function stdout(message) { - if (modes.indexOf('stdout') === -1) { return; } - process.stdout.write('stdout ' + message + '\n'); -} - -function stderr(message) { - if (modes.indexOf('stderr') === -1) { return; } - process.stderr.write('stderr ' + message + '\n'); -} - -for (var i = 0; i < max; i++) { - stdout(i); - stderr(i); -} - -process.exit(errorCode); - -stdout('fail'); -stderr('fail'); diff --git a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js b/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js deleted file mode 100644 index 8a9ed9a4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/exit/test/fixtures/log.js +++ /dev/null @@ -1,25 +0,0 @@ -var exit = require('../../lib/exit'); - -var errorCode = process.argv[2]; -var max = process.argv[3]; -var modes = process.argv.slice(4); - -function stdout(message) { - if (modes.indexOf('stdout') === -1) { return; } - process.stdout.write('stdout ' + message + '\n'); -} - -function stderr(message) { - if (modes.indexOf('stderr') === -1) { return; } - process.stderr.write('stderr ' + message + '\n'); -} - -for (var i = 0; i < max; i++) { - stdout(i); - stderr(i); -} - -exit(errorCode); - -stdout('fail'); -stderr('fail'); diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc b/spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc deleted file mode 100644 index 87189522..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.jshintrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "loopfunc": true, - "curly": true, - "eqeqeq": true, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "sub": true, - "undef": true, - "unused": true, - "boss": true, - "eqnull": true, - "node": true -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/.npmignore deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml deleted file mode 100644 index b30fcb75..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.8 -before_script: - - npm install -g grunt-cli diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js deleted file mode 100644 index 2f964a5b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/Gruntfile.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -module.exports = function(grunt) { - - // Project configuration. - grunt.initConfig({ - nodeunit: { - files: ['test/**/*_test.js'], - }, - jshint: { - options: { - jshintrc: '.jshintrc' - }, - all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'] - } - }); - - // Load plugins. - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-nodeunit'); - - // Default task. - grunt.registerTask('default', ['jshint', 'nodeunit']); - -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT b/spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT deleted file mode 100644 index bb2aad6d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 "Cowboy" Ben Alman - -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/spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md deleted file mode 100644 index 5459b93f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# findup-sync [![Build Status](https://secure.travis-ci.org/cowboy/node-findup-sync.png?branch=master)](http://travis-ci.org/cowboy/node-findup-sync) - -Find the first file matching a given pattern in the current directory or the nearest ancestor directory. - -## Getting Started -Install the module with: `npm install findup-sync` - -```js -var findup = require('findup-sync'); - -// Start looking in the CWD. -var filepath1 = findup('{a,b}*.txt'); - -// Start looking somewhere else, and ignore case (probably a good idea). -var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true}); -``` - -## Usage - -```js -findup(patternOrPatterns [, minimatchOptions]) -``` - -### patternOrPatterns -Type: `String` or `Array` -Default: none - -One or more wildcard glob patterns. Or just filenames. - -### minimatchOptions -Type: `Object` -Default: `{}` - -Options to be passed to [minimatch](https://github.com/isaacs/minimatch). - -Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here. - -## Contributing -In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). - -## Release History -2014-03-14 - v0.1.3 - Updated dependencies. -2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform. -2012-11-15 - v0.1.1 - Now works without an options object. -2012-11-01 - v0.1.0 - Initial release. diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js deleted file mode 100644 index 742a4781..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/lib/findup-sync.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * findup-sync - * https://github.com/cowboy/node-findup-sync - * - * Copyright (c) 2013 "Cowboy" Ben Alman - * Licensed under the MIT license. - */ - -'use strict'; - -// Nodejs libs. -var path = require('path'); - -// External libs. -var glob = require('glob'); -var _ = require('lodash'); - -// Search for a filename in the given directory or all parent directories. -module.exports = function(patterns, options) { - // Normalize patterns to an array. - if (!Array.isArray(patterns)) { patterns = [patterns]; } - // Create globOptions so that it can be modified without mutating the - // original object. - var globOptions = Object.create(options || {}); - globOptions.maxDepth = 1; - globOptions.cwd = path.resolve(globOptions.cwd || '.'); - - var files, lastpath; - do { - // Search for files matching patterns. - files = _(patterns).map(function(pattern) { - return glob.sync(pattern, globOptions); - }).flatten().uniq().value(); - // Return file if found. - if (files.length > 0) { - return path.resolve(path.join(globOptions.cwd, files[0])); - } - // Go up a directory. - lastpath = globOptions.cwd; - globOptions.cwd = path.resolve(globOptions.cwd, '..'); - // If parentpath is the same as basedir, we can't go any higher. - } while (globOptions.cwd !== lastpath); - - // No files were found! - return null; -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore deleted file mode 100644 index 2af4b71c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -.*.swp -test/a/ diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml deleted file mode 100644 index baa0031d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - 0.8 diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE deleted file mode 100644 index 0c44ae71..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) Isaac Z. Schlueter ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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 AUTHOR 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 AUTHOR 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/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md deleted file mode 100644 index cc691645..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# Glob - -Match files using the patterns the shell uses, like stars and stuff. - -This is a glob implementation in JavaScript. It uses the `minimatch` -library to do its matching. - -## Attention: node-glob users! - -The API has changed dramatically between 2.x and 3.x. This library is -now 100% JavaScript, and the integer flags have been replaced with an -options object. - -Also, there's an event emitter class, proper tests, and all the other -things you've come to expect from node modules. - -And best of all, no compilation! - -## Usage - -```javascript -var glob = require("glob") - -// options is optional -glob("**/*.js", options, function (er, files) { - // files is an array of filenames. - // If the `nonull` option is set, and nothing - // was found, then files is ["**/*.js"] - // er is an error object or null. -}) -``` - -## Features - -Please see the [minimatch -documentation](https://github.com/isaacs/minimatch) for more details. - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` -* [minimatch documentation](https://github.com/isaacs/minimatch) - -## glob(pattern, [options], cb) - -* `pattern` {String} Pattern to be matched -* `options` {Object} -* `cb` {Function} - * `err` {Error | null} - * `matches` {Array} filenames found matching the pattern - -Perform an asynchronous glob search. - -## glob.sync(pattern, [options]) - -* `pattern` {String} Pattern to be matched -* `options` {Object} -* return: {Array} filenames found matching the pattern - -Perform a synchronous glob search. - -## Class: glob.Glob - -Create a Glob object by instanting the `glob.Glob` class. - -```javascript -var Glob = require("glob").Glob -var mg = new Glob(pattern, options, cb) -``` - -It's an EventEmitter, and starts walking the filesystem to find matches -immediately. - -### new glob.Glob(pattern, [options], [cb]) - -* `pattern` {String} pattern to search for -* `options` {Object} -* `cb` {Function} Called when an error occurs, or matches are found - * `err` {Error | null} - * `matches` {Array} filenames found matching the pattern - -Note that if the `sync` flag is set in the options, then matches will -be immediately available on the `g.found` member. - -### Properties - -* `minimatch` The minimatch object that the glob uses. -* `options` The options object passed in. -* `error` The error encountered. When an error is encountered, the - glob object is in an undefined state, and should be discarded. -* `aborted` Boolean which is set to true when calling `abort()`. There - is no way at this time to continue a glob search after aborting, but - you can re-use the statCache to avoid having to duplicate syscalls. -* `statCache` Collection of all the stat results the glob search - performed. -* `cache` Convenience object. Each field has the following possible - values: - * `false` - Path does not exist - * `true` - Path exists - * `1` - Path exists, and is not a directory - * `2` - Path exists, and is a directory - * `[file, entries, ...]` - Path exists, is a directory, and the - array value is the results of `fs.readdir` - -### Events - -* `end` When the matching is finished, this is emitted with all the - matches found. If the `nonull` option is set, and no match was found, - then the `matches` list contains the original pattern. The matches - are sorted, unless the `nosort` flag is set. -* `match` Every time a match is found, this is emitted with the matched. -* `error` Emitted when an unexpected error is encountered, or whenever - any fs error occurs if `options.strict` is set. -* `abort` When `abort()` is called, this event is raised. - -### Methods - -* `abort` Stop the search. - -### Options - -All the options that can be passed to Minimatch can also be passed to -Glob to change pattern matching behavior. Also, some have been added, -or have glob-specific ramifications. - -All options are false by default, unless otherwise noted. - -All options are added to the glob object, as well. - -* `cwd` The current working directory in which to search. Defaults - to `process.cwd()`. -* `root` The place where patterns starting with `/` will be mounted - onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix - systems, and `C:\` or some such on Windows.) -* `dot` Include `.dot` files in normal matches and `globstar` matches. - Note that an explicit dot in a portion of the pattern will always - match dot files. -* `nomount` By default, a pattern starting with a forward-slash will be - "mounted" onto the root setting, so that a valid filesystem path is - returned. Set this flag to disable that behavior. -* `mark` Add a `/` character to directory matches. Note that this - requires additional stat calls. -* `nosort` Don't sort the results. -* `stat` Set to true to stat *all* results. This reduces performance - somewhat, and is completely unnecessary, unless `readdir` is presumed - to be an untrustworthy indicator of file existence. It will cause - ELOOP to be triggered one level sooner in the case of cyclical - symbolic links. -* `silent` When an unusual error is encountered - when attempting to read a directory, a warning will be printed to - stderr. Set the `silent` option to true to suppress these warnings. -* `strict` When an unusual error is encountered - when attempting to read a directory, the process will just continue on - in search of other matches. Set the `strict` option to raise an error - in these cases. -* `cache` See `cache` property above. Pass in a previously generated - cache object to save some fs calls. -* `statCache` A cache of results of filesystem information, to prevent - unnecessary stat calls. While it should not normally be necessary to - set this, you may pass the statCache from one glob() call to the - options object of another, if you know that the filesystem will not - change between calls. (See "Race Conditions" below.) -* `sync` Perform a synchronous glob search. -* `nounique` In some cases, brace-expanded patterns can result in the - same file showing up multiple times in the result set. By default, - this implementation prevents duplicates in the result set. - Set this flag to disable that behavior. -* `nonull` Set to never return an empty set, instead returning a set - containing the pattern itself. This is the default in glob(3). -* `nocase` Perform a case-insensitive match. Note that case-insensitive - filesystems will sometimes result in glob returning results that are - case-insensitively matched anyway, since readdir and stat will not - raise an error. -* `debug` Set to enable debug logging in minimatch and glob. -* `globDebug` Set to enable debug logging in glob, but not minimatch. - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between node-glob and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then glob returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. - -## Windows - -**Please only use forward-slashes in glob expressions.** - -Though windows uses either `/` or `\` as its path separator, only `/` -characters are used by this glob implementation. You must use -forward-slashes **only** in glob expressions. Back-slashes will always -be interpreted as escape characters, not path separators. - -Results from absolute patterns such as `/foo/*` are mounted onto the -root setting using `path.join`. On windows, this will by default result -in `/foo/*` matching `C:\foo\bar.txt`. - -## Race Conditions - -Glob searching, by its very nature, is susceptible to race conditions, -since it relies on directory walking and such. - -As a result, it is possible that a file that exists when glob looks for -it may have been deleted or modified by the time it returns the result. - -As part of its internal implementation, this program caches all stat -and readdir calls that it makes, in order to cut down on system -overhead. However, this also makes it even more susceptible to races, -especially if the cache or statCache objects are reused between glob -calls. - -Users are thus advised not to use a glob result as a guarantee of -filesystem state in the face of rapid changes. For the vast majority -of operations, this is never a problem. diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js deleted file mode 100644 index be122df0..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/g.js +++ /dev/null @@ -1,9 +0,0 @@ -var Glob = require("../").Glob - -var pattern = "test/a/**/[cg]/../[cg]" -console.log(pattern) - -var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { - console.log("matches", matches) -}) -console.log("after") diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js deleted file mode 100644 index 327a425e..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/examples/usr-local.js +++ /dev/null @@ -1,9 +0,0 @@ -var Glob = require("../").Glob - -var pattern = "{./*/*,/*,/usr/local/*}" -console.log(pattern) - -var mg = new Glob(pattern, {mark: true}, function (er, matches) { - console.log("matches", matches) -}) -console.log("after") diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js deleted file mode 100644 index f646c448..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/glob.js +++ /dev/null @@ -1,728 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// readdir(PREFIX) as ENTRIES -// If fails, END -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $]) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $]) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - - - -module.exports = glob - -var fs = require("fs") -, minimatch = require("minimatch") -, Minimatch = minimatch.Minimatch -, inherits = require("inherits") -, EE = require("events").EventEmitter -, path = require("path") -, isDir = {} -, assert = require("assert").ok - -function glob (pattern, options, cb) { - if (typeof options === "function") cb = options, options = {} - if (!options) options = {} - - if (typeof options === "number") { - deprecated() - return - } - - var g = new Glob(pattern, options, cb) - return g.sync ? g.found : g -} - -glob.fnmatch = deprecated - -function deprecated () { - throw new Error("glob's interface has changed. Please see the docs.") -} - -glob.sync = globSync -function globSync (pattern, options) { - if (typeof options === "number") { - deprecated() - return - } - - options = options || {} - options.sync = true - return glob(pattern, options) -} - -this._processingEmitQueue = false - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (!(this instanceof Glob)) { - return new Glob(pattern, options, cb) - } - - if (typeof options === "function") { - cb = options - options = null - } - - if (typeof cb === "function") { - this.on("error", cb) - this.on("end", function (matches) { - cb(null, matches) - }) - } - - options = options || {} - - this._endEmitted = false - this.EOF = {} - this._emitQueue = [] - - this.paused = false - this._processingEmitQueue = false - - this.maxDepth = options.maxDepth || 1000 - this.maxLength = options.maxLength || Infinity - this.cache = options.cache || {} - this.statCache = options.statCache || {} - - this.changedCwd = false - var cwd = process.cwd() - if (!options.hasOwnProperty("cwd")) this.cwd = cwd - else { - this.cwd = options.cwd - this.changedCwd = path.resolve(options.cwd) !== cwd - } - - this.root = options.root || path.resolve(this.cwd, "/") - this.root = path.resolve(this.root) - if (process.platform === "win32") - this.root = this.root.replace(/\\/g, "/") - - this.nomount = !!options.nomount - - if (!pattern) { - throw new Error("must provide pattern") - } - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - this.strict = options.strict !== false - this.dot = !!options.dot - this.mark = !!options.mark - this.sync = !!options.sync - this.nounique = !!options.nounique - this.nonull = !!options.nonull - this.nosort = !!options.nosort - this.nocase = !!options.nocase - this.stat = !!options.stat - - this.debug = !!options.debug || !!options.globDebug - if (this.debug) - this.log = console.error - - this.silent = !!options.silent - - var mm = this.minimatch = new Minimatch(pattern, options) - this.options = mm.options - pattern = this.pattern = mm.pattern - - this.error = null - this.aborted = false - - // list of all the patterns that ** has resolved do, so - // we can avoid visiting multiple times. - this._globstars = {} - - EE.call(this) - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - this.minimatch.set.forEach(iterator.bind(this)) - function iterator (pattern, i, set) { - this._process(pattern, 0, i, function (er) { - if (er) this.emit("error", er) - if (-- n <= 0) this._finish() - }) - } -} - -Glob.prototype.log = function () {} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - - var nou = this.nounique - , all = nou ? [] : {} - - for (var i = 0, l = this.matches.length; i < l; i ++) { - var matches = this.matches[i] - this.log("matches[%d] =", i, matches) - // do like the shell, and spit out the literal glob - if (!matches) { - if (this.nonull) { - var literal = this.minimatch.globSet[i] - if (nou) all.push(literal) - else all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) all.push.apply(all, m) - else m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) all = Object.keys(all) - - if (!this.nosort) { - all = all.sort(this.nocase ? alphasorti : alphasort) - } - - if (this.mark) { - // at *some* point we statted all of these - all = all.map(this._mark, this) - } - - this.log("emitting end", all) - - this.EOF = this.found = all - this.emitMatch(this.EOF) -} - -function alphasorti (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return alphasort(a, b) -} - -function alphasort (a, b) { - return a > b ? 1 : a < b ? -1 : 0 -} - -Glob.prototype._mark = function (p) { - var c = this.cache[p] - var m = p - if (c) { - var isDir = c === 2 || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - this.statCache[m] = this.statCache[p] - this.cache[m] = this.cache[p] - } - } - - return m -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit("abort") -} - -Glob.prototype.pause = function () { - if (this.paused) return - if (this.sync) - this.emit("error", new Error("Can't pause/resume sync glob")) - this.paused = true - this.emit("pause") -} - -Glob.prototype.resume = function () { - if (!this.paused) return - if (this.sync) - this.emit("error", new Error("Can't pause/resume sync glob")) - this.paused = false - this.emit("resume") - this._processEmitQueue() - //process.nextTick(this.emit.bind(this, "resume")) -} - -Glob.prototype.emitMatch = function (m) { - this.log('emitMatch', m) - this._emitQueue.push(m) - this._processEmitQueue() -} - -Glob.prototype._processEmitQueue = function (m) { - this.log("pEQ paused=%j processing=%j m=%j", this.paused, - this._processingEmitQueue, m) - var done = false - while (!this._processingEmitQueue && - !this.paused) { - this._processingEmitQueue = true - var m = this._emitQueue.shift() - this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m) - if (!m) { - this.log(">processEmitQueue, falsey m") - this._processingEmitQueue = false - break - } - - if (m === this.EOF || !(this.mark && !this.stat)) { - this.log("peq: unmarked, or eof") - next.call(this, 0, false) - } else if (this.statCache[m]) { - var sc = this.statCache[m] - var exists - if (sc) - exists = sc.isDirectory() ? 2 : 1 - this.log("peq: stat cached") - next.call(this, exists, exists === 2) - } else { - this.log("peq: _stat, then next") - this._stat(m, next) - } - - function next(exists, isDir) { - this.log("next", m, exists, isDir) - var ev = m === this.EOF ? "end" : "match" - - // "end" can only happen once. - assert(!this._endEmitted) - if (ev === "end") - this._endEmitted = true - - if (exists) { - // Doesn't mean it necessarily doesn't exist, it's possible - // we just didn't check because we don't care that much, or - // this is EOF anyway. - if (isDir && !m.match(/\/$/)) { - m = m + "/" - } else if (!isDir && m.match(/\/$/)) { - m = m.replace(/\/+$/, "") - } - } - this.log("emit", ev, m) - this.emit(ev, m) - this._processingEmitQueue = false - if (done && m !== this.EOF && !this.paused) - this._processEmitQueue() - } - } - done = true -} - -Glob.prototype._process = function (pattern, depth, index, cb_) { - assert(this instanceof Glob) - - var cb = function cb (er, res) { - assert(this instanceof Glob) - if (this.paused) { - if (!this._processQueue) { - this._processQueue = [] - this.once("resume", function () { - var q = this._processQueue - this._processQueue = null - q.forEach(function (cb) { cb() }) - }) - } - this._processQueue.push(cb_.bind(this, er, res)) - } else { - cb_.call(this, er, res) - } - }.bind(this) - - if (this.aborted) return cb() - - if (depth > this.maxDepth) return cb() - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === "string") { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - prefix = pattern.join("/") - this._stat(prefix, function (exists, isDir) { - // either it's there, or it isn't. - // nothing more to do, either way. - if (exists) { - if (prefix && isAbsolute(prefix) && !this.nomount) { - if (prefix.charAt(0) === "/") { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - } - } - - if (process.platform === "win32") - prefix = prefix.replace(/\\/g, "/") - - this.matches[index] = this.matches[index] || {} - this.matches[index][prefix] = true - this.emitMatch(prefix) - } - return cb() - }) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's "absolute" like /foo/bar, - // or "relative" like "../baz" - prefix = pattern.slice(0, n) - prefix = prefix.join("/") - break - } - - // get the list of entries. - var read - if (prefix === null) read = "." - else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) { - if (!prefix || !isAbsolute(prefix)) { - prefix = path.join("/", prefix) - } - read = prefix = path.resolve(prefix) - - // if (process.platform === "win32") - // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/") - - this.log('absolute: ', prefix, this.root, pattern, read) - } else { - read = prefix - } - - this.log('readdir(%j)', read, this.cwd, this.root) - - return this._readdir(read, function (er, entries) { - if (er) { - // not a directory! - // this means that, whatever else comes after this, it can never match - return cb() - } - - // globstar is special - if (pattern[n] === minimatch.GLOBSTAR) { - // test without the globstar, and with every child both below - // and replacing the globstar. - var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ] - entries.forEach(function (e) { - if (e.charAt(0) === "." && !this.dot) return - // instead of the globstar - s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) - // below the globstar - s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n))) - }, this) - - s = s.filter(function (pattern) { - var key = gsKey(pattern) - var seen = !this._globstars[key] - this._globstars[key] = true - return seen - }, this) - - if (!s.length) - return cb() - - // now asyncForEach over this - var l = s.length - , errState = null - s.forEach(function (gsPattern) { - this._process(gsPattern, depth + 1, index, function (er) { - if (errState) return - if (er) return cb(errState = er) - if (--l <= 0) return cb() - }) - }, this) - - return - } - - // not a globstar - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = pattern[n] - var rawGlob = pattern[n]._glob - , dotOk = this.dot || rawGlob.charAt(0) === "." - - entries = entries.filter(function (e) { - return (e.charAt(0) !== "." || dotOk) && - e.match(pattern[n]) - }) - - // If n === pattern.length - 1, then there's no need for the extra stat - // *unless* the user has specified "mark" or "stat" explicitly. - // We know that they exist, since the readdir returned them. - if (n === pattern.length - 1 && - !this.mark && - !this.stat) { - entries.forEach(function (e) { - if (prefix) { - if (prefix !== "/") e = prefix + "/" + e - else e = prefix + e - } - if (e.charAt(0) === "/" && !this.nomount) { - e = path.join(this.root, e) - } - - if (process.platform === "win32") - e = e.replace(/\\/g, "/") - - this.matches[index] = this.matches[index] || {} - this.matches[index][e] = true - this.emitMatch(e) - }, this) - return cb.call(this) - } - - - // now test all the remaining entries as stand-ins for that part - // of the pattern. - var l = entries.length - , errState = null - if (l === 0) return cb() // no matches possible - entries.forEach(function (e) { - var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) - this._process(p, depth + 1, index, function (er) { - if (errState) return - if (er) return cb(errState = er) - if (--l === 0) return cb.call(this) - }) - }, this) - }) - -} - -function gsKey (pattern) { - return '**' + pattern.map(function (p) { - return (p === minimatch.GLOBSTAR) ? '**' : (''+p) - }).join('/') -} - -Glob.prototype._stat = function (f, cb) { - assert(this instanceof Glob) - var abs = f - if (f.charAt(0) === "/") { - abs = path.join(this.root, f) - } else if (this.changedCwd) { - abs = path.resolve(this.cwd, f) - } - - if (f.length > this.maxLength) { - var er = new Error("Path name too long") - er.code = "ENAMETOOLONG" - er.path = f - return this._afterStat(f, abs, cb, er) - } - - this.log('stat', [this.cwd, f, '=', abs]) - - if (!this.stat && this.cache.hasOwnProperty(f)) { - var exists = this.cache[f] - , isDir = exists && (Array.isArray(exists) || exists === 2) - if (this.sync) return cb.call(this, !!exists, isDir) - return process.nextTick(cb.bind(this, !!exists, isDir)) - } - - var stat = this.statCache[abs] - if (this.sync || stat) { - var er - try { - stat = fs.statSync(abs) - } catch (e) { - er = e - } - this._afterStat(f, abs, cb, er, stat) - } else { - fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) - } -} - -Glob.prototype._afterStat = function (f, abs, cb, er, stat) { - var exists - assert(this instanceof Glob) - - if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) { - this.log("should be ENOTDIR, fake it") - - er = new Error("ENOTDIR, not a directory '" + abs + "'") - er.path = abs - er.code = "ENOTDIR" - stat = null - } - - var emit = !this.statCache[abs] - this.statCache[abs] = stat - - if (er || !stat) { - exists = false - } else { - exists = stat.isDirectory() ? 2 : 1 - if (emit) - this.emit('stat', f, stat) - } - this.cache[f] = this.cache[f] || exists - cb.call(this, !!exists, exists === 2) -} - -Glob.prototype._readdir = function (f, cb) { - assert(this instanceof Glob) - var abs = f - if (f.charAt(0) === "/") { - abs = path.join(this.root, f) - } else if (isAbsolute(f)) { - abs = f - } else if (this.changedCwd) { - abs = path.resolve(this.cwd, f) - } - - if (f.length > this.maxLength) { - var er = new Error("Path name too long") - er.code = "ENAMETOOLONG" - er.path = f - return this._afterReaddir(f, abs, cb, er) - } - - this.log('readdir', [this.cwd, f, abs]) - if (this.cache.hasOwnProperty(f)) { - var c = this.cache[f] - if (Array.isArray(c)) { - if (this.sync) return cb.call(this, null, c) - return process.nextTick(cb.bind(this, null, c)) - } - - if (!c || c === 1) { - // either ENOENT or ENOTDIR - var code = c ? "ENOTDIR" : "ENOENT" - , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) - er.path = f - er.code = code - this.log(f, er) - if (this.sync) return cb.call(this, er) - return process.nextTick(cb.bind(this, er)) - } - - // at this point, c === 2, meaning it's a dir, but we haven't - // had to read it yet, or c === true, meaning it's *something* - // but we don't have any idea what. Need to read it, either way. - } - - if (this.sync) { - var er, entries - try { - entries = fs.readdirSync(abs) - } catch (e) { - er = e - } - return this._afterReaddir(f, abs, cb, er, entries) - } - - fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) -} - -Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { - assert(this instanceof Glob) - if (entries && !er) { - this.cache[f] = entries - // if we haven't asked to stat everything for suresies, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. This also gets us one step - // further into ELOOP territory. - if (!this.mark && !this.stat) { - entries.forEach(function (e) { - if (f === "/") e = f + e - else e = f + "/" + e - this.cache[e] = true - }, this) - } - - return cb.call(this, er, entries) - } - - // now handle errors, and cache the information - if (er) switch (er.code) { - case "ENOTDIR": // totally normal. means it *does* exist. - this.cache[f] = 1 - return cb.call(this, er) - case "ENOENT": // not terribly unusual - case "ELOOP": - case "ENAMETOOLONG": - case "UNKNOWN": - this.cache[f] = false - return cb.call(this, er) - default: // some unusual error. Treat as failure. - this.cache[f] = false - if (this.strict) this.emit("error", er) - if (!this.silent) console.error("glob error", er) - return cb.call(this, er) - } -} - -var isAbsolute = process.platform === "win32" ? absWin : absUnix - -function absWin (p) { - if (absUnix(p)) return true - // pull off the device/UNC bit from a windows path. - // from node's lib/path.js - var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/ - , result = splitDeviceRe.exec(p) - , device = result[1] || '' - , isUnc = device && device.charAt(1) !== ':' - , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute - - return isAbsolute -} - -function absUnix (p) { - return p.charAt(0) === "/" || p === "" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE deleted file mode 100644 index dea3013d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -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/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md deleted file mode 100644 index b1c56658..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md +++ /dev/null @@ -1,42 +0,0 @@ -Browser-friendly inheritance fully compatible with standard node.js -[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). - -This package exports standard `inherits` from node.js `util` module in -node environment, but also provides alternative browser-friendly -implementation through [browser -field](https://gist.github.com/shtylman/4339901). Alternative -implementation is a literal copy of standard one located in standalone -module to avoid requiring of `util`. It also has a shim for old -browsers with no `Object.create` support. - -While keeping you sure you are using standard `inherits` -implementation in node.js environment, it allows bundlers such as -[browserify](https://github.com/substack/node-browserify) to not -include full `util` package to your client code if all you need is -just `inherits` function. It worth, because browser shim for `util` -package is large and `inherits` is often the single function you need -from it. - -It's recommended to use this package instead of -`require('util').inherits` for any code that has chances to be used -not only in node.js but in browser too. - -## usage - -```js -var inherits = require('inherits'); -// then use exactly as the standard one -``` - -## note on version ~1.0 - -Version ~1.0 had completely different motivation and is not compatible -neither with 2.0 nor with standard node.js `inherits`. - -If you are using version ~1.0 and planning to switch to ~2.0, be -careful: - -* new version uses `super_` instead of `super` for referencing - superclass -* new version overwrites current prototype while old one preserves any - existing fields on it diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js deleted file mode 100644 index 29f5e24f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('util').inherits diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js deleted file mode 100644 index c1e78a75..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js +++ /dev/null @@ -1,23 +0,0 @@ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json deleted file mode 100644 index 754a1144..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "inherits", - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "version": "2.0.1", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "main": "./inherits.js", - "browser": "./inherits_browser.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/inherits" - }, - "license": "ISC", - "scripts": { - "test": "node test" - }, - "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/isaacs/inherits/issues" - }, - "_id": "inherits@2.0.1", - "dist": { - "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "_from": "inherits@2", - "_npmVersion": "1.3.8", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "homepage": "https://github.com/isaacs/inherits" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js deleted file mode 100644 index fc53012d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js +++ /dev/null @@ -1,25 +0,0 @@ -var inherits = require('./inherits.js') -var assert = require('assert') - -function test(c) { - assert(c.constructor === Child) - assert(c.constructor.super_ === Parent) - assert(Object.getPrototypeOf(c) === Child.prototype) - assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) - assert(c instanceof Child) - assert(c instanceof Parent) -} - -function Child() { - Parent.call(this) - test(this) -} - -function Parent() {} - -inherits(Child, Parent) - -var c = new Child -test(c) - -console.log('ok') diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore deleted file mode 100644 index 3c3629e6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE deleted file mode 100644 index 05a40109..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -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/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md deleted file mode 100644 index 5b3967ea..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md +++ /dev/null @@ -1,218 +0,0 @@ -# minimatch - -A minimal matching utility. - -[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch) - - -This is the matching library used internally by npm. - -Eventually, it will replace the C binding in node-glob. - -It works by converting glob expressions into JavaScript `RegExp` -objects. - -## Usage - -```javascript -var minimatch = require("minimatch") - -minimatch("bar.foo", "*.foo") // true! -minimatch("bar.foo", "*.bar") // false! -minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! -``` - -## Features - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` - -## Minimatch Class - -Create a minimatch object by instanting the `minimatch.Minimatch` class. - -```javascript -var Minimatch = require("minimatch").Minimatch -var mm = new Minimatch(pattern, options) -``` - -### Properties - -* `pattern` The original pattern the minimatch object represents. -* `options` The options supplied to the constructor. -* `set` A 2-dimensional array of regexp or string expressions. - Each row in the - array corresponds to a brace-expanded pattern. Each item in the row - corresponds to a single path-part. For example, the pattern - `{a,b/c}/d` would expand to a set of patterns like: - - [ [ a, d ] - , [ b, c, d ] ] - - If a portion of the pattern doesn't have any "magic" in it - (that is, it's something like `"foo"` rather than `fo*o?`), then it - will be left as a string rather than converted to a regular - expression. - -* `regexp` Created by the `makeRe` method. A single regular expression - expressing the entire pattern. This is useful in cases where you wish - to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. -* `negate` True if the pattern is negated. -* `comment` True if the pattern is a comment. -* `empty` True if the pattern is `""`. - -### Methods - -* `makeRe` Generate the `regexp` member if necessary, and return it. - Will return `false` if the pattern is invalid. -* `match(fname)` Return true if the filename matches the pattern, or - false otherwise. -* `matchOne(fileArray, patternArray, partial)` Take a `/`-split - filename, and match it against a single row in the `regExpSet`. This - method is mainly for internal use, but is exposed so that it can be - used by a glob-walker that needs to avoid excessive filesystem calls. - -All other methods are internal, and will be called as necessary. - -## Functions - -The top-level exported function has a `cache` property, which is an LRU -cache set to store 100 items. So, calling these methods repeatedly -with the same pattern and options will use the same Minimatch object, -saving the cost of parsing it multiple times. - -### minimatch(path, pattern, options) - -Main export. Tests a path against the pattern using the options. - -```javascript -var isJS = minimatch(file, "*.js", { matchBase: true }) -``` - -### minimatch.filter(pattern, options) - -Returns a function that tests its -supplied argument, suitable for use with `Array.filter`. Example: - -```javascript -var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) -``` - -### minimatch.match(list, pattern, options) - -Match against the list of -files, in the style of fnmatch or glob. If nothing is matched, and -options.nonull is set, then return a list containing the pattern itself. - -```javascript -var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) -``` - -### minimatch.makeRe(pattern, options) - -Make a regular expression object from the pattern. - -## Options - -All options are `false` by default. - -### debug - -Dump a ton of stuff to stderr. - -### nobrace - -Do not expand `{a,b}` and `{1..3}` brace sets. - -### noglobstar - -Disable `**` matching against multiple folder names. - -### dot - -Allow patterns to match filenames starting with a period, even if -the pattern does not explicitly have a period in that spot. - -Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` -is set. - -### noext - -Disable "extglob" style patterns like `+(a|b)`. - -### nocase - -Perform a case-insensitive match. - -### nonull - -When a match is not found by `minimatch.match`, return a list containing -the pattern itself if this option is set. When not set, an empty list -is returned if there are no matches. - -### matchBase - -If set, then patterns without slashes will be matched -against the basename of the path if it contains slashes. For example, -`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. - -### nocomment - -Suppress the behavior of treating `#` at the start of a pattern as a -comment. - -### nonegate - -Suppress the behavior of treating a leading `!` character as negation. - -### flipNegate - -Returns from negate expressions the same as if they were not negated. -(Ie, true on a hit, false on a miss.) - - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between minimatch and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then minimatch.match returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js deleted file mode 100644 index 45396789..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,1061 +0,0 @@ -;(function (require, exports, module, platform) { - -if (module) module.exports = minimatch -else exports.minimatch = minimatch - -if (!require) { - require = function (id) { - switch (id) { - case "sigmund": return function sigmund (obj) { - return JSON.stringify(obj) - } - case "path": return { basename: function (f) { - f = f.split(/[\/\\]/) - var e = f.pop() - if (!e) e = f.pop() - return e - }} - case "lru-cache": return function LRUCache () { - // not quite an LRU, but still space-limited. - var cache = {} - var cnt = 0 - this.set = function (k, v) { - cnt ++ - if (cnt >= 100) cache = {} - cache[k] = v - } - this.get = function (k) { return cache[k] } - } - } - } -} - -minimatch.Minimatch = Minimatch - -var LRU = require("lru-cache") - , cache = minimatch.cache = new LRU({max: 100}) - , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} - , sigmund = require("sigmund") - -var path = require("path") - // any single thing other than / - // don't need to escape / when using new RegExp() - , qmark = "[^/]" - - // * => any number of characters - , star = qmark + "*?" - - // ** when dots are allowed. Anything goes, except .. and . - // not (^ or / followed by one or two dots followed by $ or /), - // followed by anything, any number of times. - , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" - - // not a ^ or / followed by a dot, - // followed by anything, any number of times. - , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" - - // characters that need to be escaped in RegExp. - , reSpecials = charSet("().*{}+?[]^$\\!") - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split("").reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - - -function minimatch (p, pattern, options) { - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required") - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === "#") { - return false - } - - // "" only matches "" - if (pattern.trim() === "") return p === "" - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options, cache) - } - - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required") - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. - if (platform === "win32") { - pattern = pattern.split("\\").join("/") - } - - // lru storage. - // these things aren't particularly big, but walking down the string - // and turning it into a regexp can get pretty costly. - var cacheKey = pattern + "\n" + sigmund(options) - var cached = minimatch.cache.get(cacheKey) - if (cached) return cached - minimatch.cache.set(cacheKey, this) - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function() {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === "#") { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return -1 === s.indexOf(false) - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - , negate = false - , options = this.options - , negateOffset = 0 - - if (options.nonegate) return - - for ( var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === "!" - ; i ++) { - negate = !negate - negateOffset ++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return new Minimatch(pattern, options).braceExpand() -} - -Minimatch.prototype.braceExpand = braceExpand -function braceExpand (pattern, options) { - options = options || this.options - pattern = typeof pattern === "undefined" - ? this.pattern : pattern - - if (typeof pattern === "undefined") { - throw new Error("undefined pattern") - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - var escaping = false - - // examples and comments refer to this crazy pattern: - // a{b,c{d,e},{f,g}h}x{y,z} - // expected: - // abxy - // abxz - // acdxy - // acdxz - // acexy - // acexz - // afhxy - // afhxz - // aghxy - // aghxz - - // everything before the first \{ is just a prefix. - // So, we pluck that off, and work with the rest, - // and then prepend it to everything we find. - if (pattern.charAt(0) !== "{") { - this.debug(pattern) - var prefix = null - for (var i = 0, l = pattern.length; i < l; i ++) { - var c = pattern.charAt(i) - this.debug(i, c) - if (c === "\\") { - escaping = !escaping - } else if (c === "{" && !escaping) { - prefix = pattern.substr(0, i) - break - } - } - - // actually no sets, all { were escaped. - if (prefix === null) { - this.debug("no sets") - return [pattern] - } - - var tail = braceExpand.call(this, pattern.substr(i), options) - return tail.map(function (t) { - return prefix + t - }) - } - - // now we have something like: - // {b,c{d,e},{f,g}h}x{y,z} - // walk through the set, expanding each part, until - // the set ends. then, we'll expand the suffix. - // If the set only has a single member, then'll put the {} back - - // first, handle numeric sets, since they're easier - var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/) - if (numset) { - this.debug("numset", numset[1], numset[2]) - var suf = braceExpand.call(this, pattern.substr(numset[0].length), options) - , start = +numset[1] - , end = +numset[2] - , inc = start > end ? -1 : 1 - , set = [] - for (var i = start; i != (end + inc); i += inc) { - // append all the suffixes - for (var ii = 0, ll = suf.length; ii < ll; ii ++) { - set.push(i + suf[ii]) - } - } - return set - } - - // ok, walk through the set - // We hope, somewhat optimistically, that there - // will be a } at the end. - // If the closing brace isn't found, then the pattern is - // interpreted as braceExpand("\\" + pattern) so that - // the leading \{ will be interpreted literally. - var i = 1 // skip the \{ - , depth = 1 - , set = [] - , member = "" - , sawEnd = false - , escaping = false - - function addMember () { - set.push(member) - member = "" - } - - this.debug("Entering for") - FOR: for (i = 1, l = pattern.length; i < l; i ++) { - var c = pattern.charAt(i) - this.debug("", i, c) - - if (escaping) { - escaping = false - member += "\\" + c - } else { - switch (c) { - case "\\": - escaping = true - continue - - case "{": - depth ++ - member += "{" - continue - - case "}": - depth -- - // if this closes the actual set, then we're done - if (depth === 0) { - addMember() - // pluck off the close-brace - i ++ - break FOR - } else { - member += c - continue - } - - case ",": - if (depth === 1) { - addMember() - } else { - member += c - } - continue - - default: - member += c - continue - } // switch - } // else - } // for - - // now we've either finished the set, and the suffix is - // pattern.substr(i), or we have *not* closed the set, - // and need to escape the leading brace - if (depth !== 0) { - this.debug("didn't close", pattern) - return braceExpand.call(this, "\\" + pattern, options) - } - - // x{y,z} -> ["xy", "xz"] - this.debug("set", set) - this.debug("suffix", pattern.substr(i)) - var suf = braceExpand.call(this, pattern.substr(i), options) - // ["b", "c{d,e}","{f,g}h"] -> - // [["b"], ["cd", "ce"], ["fh", "gh"]] - var addBraces = set.length === 1 - this.debug("set pre-expanded", set) - set = set.map(function (p) { - return braceExpand.call(this, p, options) - }, this) - this.debug("set expanded", set) - - - // [["b"], ["cd", "ce"], ["fh", "gh"]] -> - // ["b", "cd", "ce", "fh", "gh"] - set = set.reduce(function (l, r) { - return l.concat(r) - }) - - if (addBraces) { - set = set.map(function (s) { - return "{" + s + "}" - }) - } - - // now attach the suffixes. - var ret = [] - for (var i = 0, l = set.length; i < l; i ++) { - for (var ii = 0, ll = suf.length; ii < ll; ii ++) { - ret.push(set[i] + suf[ii]) - } - } - return ret -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === "**") return GLOBSTAR - if (pattern === "") return "" - - var re = "" - , hasMagic = !!options.nocase - , escaping = false - // ? => one single character - , patternListStack = [] - , plType - , stateChar - , inClass = false - , reClassStart = -1 - , classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - , patternStart = pattern.charAt(0) === "." ? "" // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" - : "(?!\\.)" - , self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case "*": - re += star - hasMagic = true - break - case "?": - re += qmark - hasMagic = true - break - default: - re += "\\"+stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for ( var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i ++ ) { - - this.debug("%s\t%s %s %j", pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += "\\" + c - escaping = false - continue - } - - SWITCH: switch (c) { - case "/": - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case "\\": - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case "?": - case "*": - case "+": - case "@": - case "!": - this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === "!" && i === classStart + 1) c = "^" - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case "(": - if (inClass) { - re += "(" - continue - } - - if (!stateChar) { - re += "\\(" - continue - } - - plType = stateChar - patternListStack.push({ type: plType - , start: i - 1 - , reStart: re.length }) - // negation is (?:(?!js)[^/]*) - re += stateChar === "!" ? "(?:(?!" : "(?:" - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ")": - if (inClass || !patternListStack.length) { - re += "\\)" - continue - } - - clearStateChar() - hasMagic = true - re += ")" - plType = patternListStack.pop().type - // negation is (?:(?!js)[^/]*) - // The others are (?:) - switch (plType) { - case "!": - re += "[^/]*?)" - break - case "?": - case "+": - case "*": re += plType - case "@": break // the default anyway - } - continue - - case "|": - if (inClass || !patternListStack.length || escaping) { - re += "\\|" - escaping = false - continue - } - - clearStateChar() - re += "|" - continue - - // these are mostly the same in regexp and glob - case "[": - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += "\\" + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case "]": - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += "\\" + c - escaping = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === "^" && inClass)) { - re += "\\" - } - - re += c - - } // switch - } // for - - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - var cs = pattern.substr(classStart + 1) - , sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + "\\[" + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - var pl - while (pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + 3) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = "\\" - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + "|" - }) - - this.debug("tail=%j\n %s", tail, tail) - var t = pl.type === "*" ? star - : pl.type === "?" ? qmark - : "\\" + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) - + t + "\\(" - + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += "\\\\" - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case ".": - case "[": - case "(": addPatternStart = true - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== "" && hasMagic) re = "(?=.)" + re - - if (addPatternStart) re = patternStart + re - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [ re, hasMagic ] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? "i" : "" - , regExp = new RegExp("^" + re + "$", flags) - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) return this.regexp = false - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - , flags = options.nocase ? "i" : "" - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === "string") ? regExpEscape(p) - : p._src - }).join("\\\/") - }).join("|") - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = "^(?:" + re + ")$" - - // can match anything, as long as it's not this. - if (this.negate) re = "^(?!" + re + ").*$" - - try { - return this.regexp = new RegExp(re, flags) - } catch (ex) { - return this.regexp = false - } -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug("match", f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === "" - - if (f === "/" && partial) return true - - var options = this.options - - // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. - if (platform === "win32") { - f = f.split("\\").join("/") - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, "split", f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, "set", set) - - // Find the basename of the path by looking for the last non-empty segment - var filename; - for (var i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (var i = 0, l = set.length; i < l; i ++) { - var pattern = set[i], file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug("matchOne", - { "this": this - , file: file - , pattern: pattern }) - - this.debug("matchOne", file.length, pattern.length) - - for ( var fi = 0 - , pi = 0 - , fl = file.length - , pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi ++, pi ++ ) { - - this.debug("matchOne loop") - var p = pattern[pi] - , f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - , pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for ( ; fi < fl; fi ++) { - if (file[fi] === "." || file[fi] === ".." || - (!options.dot && file[fi].charAt(0) === ".")) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - WHILE: while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', - file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === "." || swallowee === ".." || - (!options.dot && swallowee.charAt(0) === ".")) { - this.debug("dot detected!", file, fr, pattern, pr) - break WHILE - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr ++ - } - } - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug("\n>>> no match, partial?", file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === "string") { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug("string match", p, f, hit) - } else { - hit = f.match(p) - this.debug("pattern match", p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === "") - return emptyFileEnd - } - - // should be unreachable. - throw new Error("wtf?") -} - - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, "$1") -} - - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") -} - -})( typeof require === "function" ? require : null, - this, - typeof module === "object" ? module : null, - typeof process === "object" ? process.platform : "win32" - ) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore deleted file mode 100644 index 07e6e472..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS deleted file mode 100644 index 4a0bc503..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +++ /dev/null @@ -1,14 +0,0 @@ -# Authors, sorted by whether or not they are me -Isaac Z. Schlueter -Brian Cottingham -Carlos Brito Lage -Jesse Dailey -Kevin O'Hara -Marco Rogers -Mark Cavage -Marko Mikulicic -Nathan Rajlich -Satheesh Natesan -Trent Mick -ashleybrener -n4kz diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE deleted file mode 100644 index 05a40109..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -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/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md deleted file mode 100644 index 03ee0f98..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# lru cache - -A cache object that deletes the least-recently-used items. - -## Usage: - -```javascript -var LRU = require("lru-cache") - , options = { max: 500 - , length: function (n) { return n * 2 } - , dispose: function (key, n) { n.close() } - , maxAge: 1000 * 60 * 60 } - , cache = LRU(options) - , otherCache = LRU(50) // sets just the max size - -cache.set("key", "value") -cache.get("key") // "value" - -cache.reset() // empty the cache -``` - -If you put more stuff in it, then items will fall out. - -If you try to put an oversized thing in it, then it'll fall out right -away. - -## Options - -* `max` The maximum size of the cache, checked by applying the length - function to all values in the cache. Not setting this is kind of - silly, since that's the whole purpose of this lib, but it defaults - to `Infinity`. -* `maxAge` Maximum age in ms. Items are not pro-actively pruned out - as they age, but if you try to get an item that is too old, it'll - drop it and return undefined instead of giving it to you. -* `length` Function that is used to calculate the length of stored - items. If you're storing strings or buffers, then you probably want - to do something like `function(n){return n.length}`. The default is - `function(n){return 1}`, which is fine if you want to store `n` - like-sized things. -* `dispose` Function that is called on items when they are dropped - from the cache. This can be handy if you want to close file - descriptors or do other cleanup tasks when items are no longer - accessible. Called with `key, value`. It's called *before* - actually removing the item from the internal cache, so if you want - to immediately put it back in, you'll have to do that in a - `nextTick` or `setTimeout` callback or it won't do anything. -* `stale` By default, if you set a `maxAge`, it'll only actually pull - stale items out of the cache when you `get(key)`. (That is, it's - not pre-emptively doing a `setTimeout` or anything.) If you set - `stale:true`, it'll return the stale value before deleting it. If - you don't set this, then it'll return `undefined` when you try to - get a stale entry, as if it had already been deleted. - -## API - -* `set(key, value)` -* `get(key) => value` - - Both of these will update the "recently used"-ness of the key. - They do what you think. - -* `peek(key)` - - Returns the key value (or `undefined` if not found) without - updating the "recently used"-ness of the key. - - (If you find yourself using this a lot, you *might* be using the - wrong sort of data structure, but there are some use cases where - it's handy.) - -* `del(key)` - - Deletes a key out of the cache. - -* `reset()` - - Clear the cache entirely, throwing away all values. - -* `has(key)` - - Check if a key is in the cache, without updating the recent-ness - or deleting it for being stale. - -* `forEach(function(value,key,cache), [thisp])` - - Just like `Array.prototype.forEach`. Iterates over all the keys - in the cache, in order of recent-ness. (Ie, more recently used - items are iterated over first.) - -* `keys()` - - Return an array of the keys in the cache. - -* `values()` - - Return an array of the values in the cache. diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js deleted file mode 100644 index d1d13817..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +++ /dev/null @@ -1,252 +0,0 @@ -;(function () { // closure for web browsers - -if (typeof module === 'object' && module.exports) { - module.exports = LRUCache -} else { - // just set the global for non-node platforms. - this.LRUCache = LRUCache -} - -function hOP (obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key) -} - -function naiveLength () { return 1 } - -function LRUCache (options) { - if (!(this instanceof LRUCache)) - return new LRUCache(options) - - if (typeof options === 'number') - options = { max: options } - - if (!options) - options = {} - - this._max = options.max - // Kind of weird to have a default max of Infinity, but oh well. - if (!this._max || !(typeof this._max === "number") || this._max <= 0 ) - this._max = Infinity - - this._lengthCalculator = options.length || naiveLength - if (typeof this._lengthCalculator !== "function") - this._lengthCalculator = naiveLength - - this._allowStale = options.stale || false - this._maxAge = options.maxAge || null - this._dispose = options.dispose - this.reset() -} - -// resize the cache when the max changes. -Object.defineProperty(LRUCache.prototype, "max", - { set : function (mL) { - if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity - this._max = mL - if (this._length > this._max) trim(this) - } - , get : function () { return this._max } - , enumerable : true - }) - -// resize the cache when the lengthCalculator changes. -Object.defineProperty(LRUCache.prototype, "lengthCalculator", - { set : function (lC) { - if (typeof lC !== "function") { - this._lengthCalculator = naiveLength - this._length = this._itemCount - for (var key in this._cache) { - this._cache[key].length = 1 - } - } else { - this._lengthCalculator = lC - this._length = 0 - for (var key in this._cache) { - this._cache[key].length = this._lengthCalculator(this._cache[key].value) - this._length += this._cache[key].length - } - } - - if (this._length > this._max) trim(this) - } - , get : function () { return this._lengthCalculator } - , enumerable : true - }) - -Object.defineProperty(LRUCache.prototype, "length", - { get : function () { return this._length } - , enumerable : true - }) - - -Object.defineProperty(LRUCache.prototype, "itemCount", - { get : function () { return this._itemCount } - , enumerable : true - }) - -LRUCache.prototype.forEach = function (fn, thisp) { - thisp = thisp || this - var i = 0; - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - i++ - var hit = this._lruList[k] - if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { - del(this, hit) - if (!this._allowStale) hit = undefined - } - if (hit) { - fn.call(thisp, hit.value, hit.key, this) - } - } -} - -LRUCache.prototype.keys = function () { - var keys = new Array(this._itemCount) - var i = 0 - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - var hit = this._lruList[k] - keys[i++] = hit.key - } - return keys -} - -LRUCache.prototype.values = function () { - var values = new Array(this._itemCount) - var i = 0 - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - var hit = this._lruList[k] - values[i++] = hit.value - } - return values -} - -LRUCache.prototype.reset = function () { - if (this._dispose && this._cache) { - for (var k in this._cache) { - this._dispose(k, this._cache[k].value) - } - } - - this._cache = Object.create(null) // hash of items by key - this._lruList = Object.create(null) // list of items in order of use recency - this._mru = 0 // most recently used - this._lru = 0 // least recently used - this._length = 0 // number of items in the list - this._itemCount = 0 -} - -// Provided for debugging/dev purposes only. No promises whatsoever that -// this API stays stable. -LRUCache.prototype.dump = function () { - return this._cache -} - -LRUCache.prototype.dumpLru = function () { - return this._lruList -} - -LRUCache.prototype.set = function (key, value) { - if (hOP(this._cache, key)) { - // dispose of the old one before overwriting - if (this._dispose) this._dispose(key, this._cache[key].value) - if (this._maxAge) this._cache[key].now = Date.now() - this._cache[key].value = value - this.get(key) - return true - } - - var len = this._lengthCalculator(value) - var age = this._maxAge ? Date.now() : 0 - var hit = new Entry(key, value, this._mru++, len, age) - - // oversized objects fall out of cache automatically. - if (hit.length > this._max) { - if (this._dispose) this._dispose(key, value) - return false - } - - this._length += hit.length - this._lruList[hit.lu] = this._cache[key] = hit - this._itemCount ++ - - if (this._length > this._max) trim(this) - return true -} - -LRUCache.prototype.has = function (key) { - if (!hOP(this._cache, key)) return false - var hit = this._cache[key] - if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { - return false - } - return true -} - -LRUCache.prototype.get = function (key) { - return get(this, key, true) -} - -LRUCache.prototype.peek = function (key) { - return get(this, key, false) -} - -LRUCache.prototype.pop = function () { - var hit = this._lruList[this._lru] - del(this, hit) - return hit || null -} - -LRUCache.prototype.del = function (key) { - del(this, this._cache[key]) -} - -function get (self, key, doUse) { - var hit = self._cache[key] - if (hit) { - if (self._maxAge && (Date.now() - hit.now > self._maxAge)) { - del(self, hit) - if (!self._allowStale) hit = undefined - } else { - if (doUse) use(self, hit) - } - if (hit) hit = hit.value - } - return hit -} - -function use (self, hit) { - shiftLU(self, hit) - hit.lu = self._mru ++ - self._lruList[hit.lu] = hit -} - -function trim (self) { - while (self._lru < self._mru && self._length > self._max) - del(self, self._lruList[self._lru]) -} - -function shiftLU (self, hit) { - delete self._lruList[ hit.lu ] - while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++ -} - -function del (self, hit) { - if (hit) { - if (self._dispose) self._dispose(hit.key, hit.value) - self._length -= hit.length - self._itemCount -- - delete self._cache[ hit.key ] - shiftLU(self, hit) - } -} - -// classy, since V8 prefers predictable objects. -function Entry (key, value, lu, length, now) { - this.key = key - this.value = value - this.lu = lu - this.length = length - this.now = now -} - -})() diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json deleted file mode 100644 index 2474729b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "lru-cache", - "description": "A cache object that deletes the least-recently-used items.", - "version": "2.5.0", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "scripts": { - "test": "tap test --gc" - }, - "main": "lib/lru-cache.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-lru-cache.git" - }, - "devDependencies": { - "tap": "", - "weak": "" - }, - "license": { - "type": "MIT", - "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/node-lru-cache/issues" - }, - "homepage": "https://github.com/isaacs/node-lru-cache", - "_id": "lru-cache@2.5.0", - "dist": { - "shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb", - "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz" - }, - "_from": "lru-cache@2", - "_npmVersion": "1.3.15", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb", - "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js deleted file mode 100644 index f72697c4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js +++ /dev/null @@ -1,369 +0,0 @@ -var test = require("tap").test - , LRU = require("../") - -test("basic", function (t) { - var cache = new LRU({max: 10}) - cache.set("key", "value") - t.equal(cache.get("key"), "value") - t.equal(cache.get("nada"), undefined) - t.equal(cache.length, 1) - t.equal(cache.max, 10) - t.end() -}) - -test("least recently set", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), "B") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("lru recently gotten", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - cache.get("a") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), undefined) - t.equal(cache.get("a"), "A") - t.end() -}) - -test("del", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.del("a") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("max", function (t) { - var cache = new LRU(3) - - // test changing the max, verify that the LRU items get dropped. - cache.max = 100 - for (var i = 0; i < 100; i ++) cache.set(i, i) - t.equal(cache.length, 100) - for (var i = 0; i < 100; i ++) { - t.equal(cache.get(i), i) - } - cache.max = 3 - t.equal(cache.length, 3) - for (var i = 0; i < 97; i ++) { - t.equal(cache.get(i), undefined) - } - for (var i = 98; i < 100; i ++) { - t.equal(cache.get(i), i) - } - - // now remove the max restriction, and try again. - cache.max = "hello" - for (var i = 0; i < 100; i ++) cache.set(i, i) - t.equal(cache.length, 100) - for (var i = 0; i < 100; i ++) { - t.equal(cache.get(i), i) - } - // should trigger an immediate resize - cache.max = 3 - t.equal(cache.length, 3) - for (var i = 0; i < 97; i ++) { - t.equal(cache.get(i), undefined) - } - for (var i = 98; i < 100; i ++) { - t.equal(cache.get(i), i) - } - t.end() -}) - -test("reset", function (t) { - var cache = new LRU(10) - cache.set("a", "A") - cache.set("b", "B") - cache.reset() - t.equal(cache.length, 0) - t.equal(cache.max, 10) - t.equal(cache.get("a"), undefined) - t.equal(cache.get("b"), undefined) - t.end() -}) - - -// Note: `.dump()` is a debugging tool only. No guarantees are made -// about the format/layout of the response. -test("dump", function (t) { - var cache = new LRU(10) - var d = cache.dump(); - t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache") - cache.set("a", "A") - var d = cache.dump() // { a: { key: "a", value: "A", lu: 0 } } - t.ok(d.a) - t.equal(d.a.key, "a") - t.equal(d.a.value, "A") - t.equal(d.a.lu, 0) - - cache.set("b", "B") - cache.get("b") - d = cache.dump() - t.ok(d.b) - t.equal(d.b.key, "b") - t.equal(d.b.value, "B") - t.equal(d.b.lu, 2) - - t.end() -}) - - -test("basic with weighed length", function (t) { - var cache = new LRU({ - max: 100, - length: function (item) { return item.size } - }) - cache.set("key", {val: "value", size: 50}) - t.equal(cache.get("key").val, "value") - t.equal(cache.get("nada"), undefined) - t.equal(cache.lengthCalculator(cache.get("key")), 50) - t.equal(cache.length, 50) - t.equal(cache.max, 100) - t.end() -}) - - -test("weighed length item too large", function (t) { - var cache = new LRU({ - max: 10, - length: function (item) { return item.size } - }) - t.equal(cache.max, 10) - - // should fall out immediately - cache.set("key", {val: "value", size: 50}) - - t.equal(cache.length, 0) - t.equal(cache.get("key"), undefined) - t.end() -}) - -test("least recently set with weighed length", function (t) { - var cache = new LRU({ - max:8, - length: function (item) { return item.length } - }) - cache.set("a", "A") - cache.set("b", "BB") - cache.set("c", "CCC") - cache.set("d", "DDDD") - t.equal(cache.get("d"), "DDDD") - t.equal(cache.get("c"), "CCC") - t.equal(cache.get("b"), undefined) - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("lru recently gotten with weighed length", function (t) { - var cache = new LRU({ - max: 8, - length: function (item) { return item.length } - }) - cache.set("a", "A") - cache.set("b", "BB") - cache.set("c", "CCC") - cache.get("a") - cache.get("b") - cache.set("d", "DDDD") - t.equal(cache.get("c"), undefined) - t.equal(cache.get("d"), "DDDD") - t.equal(cache.get("b"), "BB") - t.equal(cache.get("a"), "A") - t.end() -}) - -test("set returns proper booleans", function(t) { - var cache = new LRU({ - max: 5, - length: function (item) { return item.length } - }) - - t.equal(cache.set("a", "A"), true) - - // should return false for max exceeded - t.equal(cache.set("b", "donuts"), false) - - t.equal(cache.set("b", "B"), true) - t.equal(cache.set("c", "CCCC"), true) - t.end() -}) - -test("drop the old items", function(t) { - var cache = new LRU({ - max: 5, - maxAge: 50 - }) - - cache.set("a", "A") - - setTimeout(function () { - cache.set("b", "b") - t.equal(cache.get("a"), "A") - }, 25) - - setTimeout(function () { - cache.set("c", "C") - // timed out - t.notOk(cache.get("a")) - }, 60) - - setTimeout(function () { - t.notOk(cache.get("b")) - t.equal(cache.get("c"), "C") - }, 90) - - setTimeout(function () { - t.notOk(cache.get("c")) - t.end() - }, 155) -}) - -test("disposal function", function(t) { - var disposed = false - var cache = new LRU({ - max: 1, - dispose: function (k, n) { - disposed = n - } - }) - - cache.set(1, 1) - cache.set(2, 2) - t.equal(disposed, 1) - cache.set(3, 3) - t.equal(disposed, 2) - cache.reset() - t.equal(disposed, 3) - t.end() -}) - -test("disposal function on too big of item", function(t) { - var disposed = false - var cache = new LRU({ - max: 1, - length: function (k) { - return k.length - }, - dispose: function (k, n) { - disposed = n - } - }) - var obj = [ 1, 2 ] - - t.equal(disposed, false) - cache.set("obj", obj) - t.equal(disposed, obj) - t.end() -}) - -test("has()", function(t) { - var cache = new LRU({ - max: 1, - maxAge: 10 - }) - - cache.set('foo', 'bar') - t.equal(cache.has('foo'), true) - cache.set('blu', 'baz') - t.equal(cache.has('foo'), false) - t.equal(cache.has('blu'), true) - setTimeout(function() { - t.equal(cache.has('blu'), false) - t.end() - }, 15) -}) - -test("stale", function(t) { - var cache = new LRU({ - maxAge: 10, - stale: true - }) - - cache.set('foo', 'bar') - t.equal(cache.get('foo'), 'bar') - t.equal(cache.has('foo'), true) - setTimeout(function() { - t.equal(cache.has('foo'), false) - t.equal(cache.get('foo'), 'bar') - t.equal(cache.get('foo'), undefined) - t.end() - }, 15) -}) - -test("lru update via set", function(t) { - var cache = LRU({ max: 2 }); - - cache.set('foo', 1); - cache.set('bar', 2); - cache.del('bar'); - cache.set('baz', 3); - cache.set('qux', 4); - - t.equal(cache.get('foo'), undefined) - t.equal(cache.get('bar'), undefined) - t.equal(cache.get('baz'), 3) - t.equal(cache.get('qux'), 4) - t.end() -}) - -test("least recently set w/ peek", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - t.equal(cache.peek("a"), "A") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), "B") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("pop the least used item", function (t) { - var cache = new LRU(3) - , last - - cache.set("a", "A") - cache.set("b", "B") - cache.set("c", "C") - - t.equal(cache.length, 3) - t.equal(cache.max, 3) - - // Ensure we pop a, c, b - cache.get("b", "B") - - last = cache.pop() - t.equal(last.key, "a") - t.equal(last.value, "A") - t.equal(cache.length, 2) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last.key, "c") - t.equal(last.value, "C") - t.equal(cache.length, 1) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last.key, "b") - t.equal(last.value, "B") - t.equal(cache.length, 0) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last, null) - t.equal(cache.length, 0) - t.equal(cache.max, 3) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js deleted file mode 100644 index eefb80d9..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +++ /dev/null @@ -1,52 +0,0 @@ -var test = require('tap').test -var LRU = require('../') - -test('forEach', function (t) { - var l = new LRU(5) - for (var i = 0; i < 10; i ++) { - l.set(i.toString(), i.toString(2)) - } - - var i = 9 - l.forEach(function (val, key, cache) { - t.equal(cache, l) - t.equal(key, i.toString()) - t.equal(val, i.toString(2)) - i -= 1 - }) - - // get in order of most recently used - l.get(6) - l.get(8) - - var order = [ 8, 6, 9, 7, 5 ] - var i = 0 - - l.forEach(function (val, key, cache) { - var j = order[i ++] - t.equal(cache, l) - t.equal(key, j.toString()) - t.equal(val, j.toString(2)) - }) - - t.end() -}) - -test('keys() and values()', function (t) { - var l = new LRU(5) - for (var i = 0; i < 10; i ++) { - l.set(i.toString(), i.toString(2)) - } - - t.similar(l.keys(), ['9', '8', '7', '6', '5']) - t.similar(l.values(), ['1001', '1000', '111', '110', '101']) - - // get in order of most recently used - l.get(6) - l.get(8) - - t.similar(l.keys(), ['8', '6', '9', '7', '5']) - t.similar(l.values(), ['1000', '110', '1001', '111', '101']) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js deleted file mode 100644 index 7af45b02..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node --expose_gc - -var weak = require('weak'); -var test = require('tap').test -var LRU = require('../') -var l = new LRU({ max: 10 }) -var refs = 0 -function X() { - refs ++ - weak(this, deref) -} - -function deref() { - refs -- -} - -test('no leaks', function (t) { - // fill up the cache - for (var i = 0; i < 100; i++) { - l.set(i, new X); - // throw some gets in there, too. - if (i % 2 === 0) - l.get(i / 2) - } - - gc() - - var start = process.memoryUsage() - - // capture the memory - var startRefs = refs - - // do it again, but more - for (var i = 0; i < 10000; i++) { - l.set(i, new X); - // throw some gets in there, too. - if (i % 2 === 0) - l.get(i / 2) - } - - gc() - - var end = process.memoryUsage() - t.equal(refs, startRefs, 'no leaky refs') - - console.error('start: %j\n' + - 'end: %j', start, end); - t.pass(); - t.end(); -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE deleted file mode 100644 index 0c44ae71..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) Isaac Z. Schlueter ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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 AUTHOR 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 AUTHOR 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/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md deleted file mode 100644 index 7e365129..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# sigmund - -Quick and dirty signatures for Objects. - -This is like a much faster `deepEquals` comparison, which returns a -string key suitable for caches and the like. - -## Usage - -```javascript -function doSomething (someObj) { - var key = sigmund(someObj, maxDepth) // max depth defaults to 10 - var cached = cache.get(key) - if (cached) return cached) - - var result = expensiveCalculation(someObj) - cache.set(key, result) - return result -} -``` - -The resulting key will be as unique and reproducible as calling -`JSON.stringify` or `util.inspect` on the object, but is much faster. -In order to achieve this speed, some differences are glossed over. -For example, the object `{0:'foo'}` will be treated identically to the -array `['foo']`. - -Also, just as there is no way to summon the soul from the scribblings -of a cocain-addled psychoanalyst, there is no way to revive the object -from the signature string that sigmund gives you. In fact, it's -barely even readable. - -As with `sys.inspect` and `JSON.stringify`, larger objects will -produce larger signature strings. - -Because sigmund is a bit less strict than the more thorough -alternatives, the strings will be shorter, and also there is a -slightly higher chance for collisions. For example, these objects -have the same signature: - - var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} - var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} - -Like a good Freudian, sigmund is most effective when you already have -some understanding of what you're looking for. It can help you help -yourself, but you must be willing to do some work as well. - -Cycles are handled, and cyclical objects are silently omitted (though -the key is included in the signature output.) - -The second argument is the maximum depth, which defaults to 10, -because that is the maximum object traversal depth covered by most -insurance carriers. diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js deleted file mode 100644 index 5acfd6d9..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js +++ /dev/null @@ -1,283 +0,0 @@ -// different ways to id objects -// use a req/res pair, since it's crazy deep and cyclical - -// sparseFE10 and sigmund are usually pretty close, which is to be expected, -// since they are essentially the same algorithm, except that sigmund handles -// regular expression objects properly. - - -var http = require('http') -var util = require('util') -var sigmund = require('./sigmund.js') -var sreq, sres, creq, cres, test - -http.createServer(function (q, s) { - sreq = q - sres = s - sres.end('ok') - this.close(function () { setTimeout(function () { - start() - }, 200) }) -}).listen(1337, function () { - creq = http.get({ port: 1337 }) - creq.on('response', function (s) { cres = s }) -}) - -function start () { - test = [sreq, sres, creq, cres] - // test = sreq - // sreq.sres = sres - // sreq.creq = creq - // sreq.cres = cres - - for (var i in exports.compare) { - console.log(i) - var hash = exports.compare[i]() - console.log(hash) - console.log(hash.length) - console.log('') - } - - require('bench').runMain() -} - -function customWs (obj, md, d) { - d = d || 0 - var to = typeof obj - if (to === 'undefined' || to === 'function' || to === null) return '' - if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '') - - if (Array.isArray(obj)) { - return obj.map(function (i, _, __) { - return customWs(i, md, d + 1) - }).reduce(function (a, b) { return a + b }, '') - } - - var keys = Object.keys(obj) - return keys.map(function (k, _, __) { - return k + ':' + customWs(obj[k], md, d + 1) - }).reduce(function (a, b) { return a + b }, '') -} - -function custom (obj, md, d) { - d = d || 0 - var to = typeof obj - if (to === 'undefined' || to === 'function' || to === null) return '' - if (d > md || !obj || to !== 'object') return '' + obj - - if (Array.isArray(obj)) { - return obj.map(function (i, _, __) { - return custom(i, md, d + 1) - }).reduce(function (a, b) { return a + b }, '') - } - - var keys = Object.keys(obj) - return keys.map(function (k, _, __) { - return k + ':' + custom(obj[k], md, d + 1) - }).reduce(function (a, b) { return a + b }, '') -} - -function sparseFE2 (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - Object.keys(v).forEach(function (k, _, __) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') return - var to = typeof v[k] - if (to === 'function' || to === 'undefined') return - soFar += k + ':' - ch(v[k], depth + 1) - }) - soFar += '}' - } - ch(obj, 0) - return soFar -} - -function sparseFE (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - Object.keys(v).forEach(function (k, _, __) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') return - var to = typeof v[k] - if (to === 'function' || to === 'undefined') return - soFar += k - ch(v[k], depth + 1) - }) - } - ch(obj, 0) - return soFar -} - -function sparse (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k - ch(v[k], depth + 1) - } - } - ch(obj, 0) - return soFar -} - -function noCommas (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k + ':' - ch(v[k], depth + 1) - } - soFar += '}' - } - ch(obj, 0) - return soFar -} - - -function flatten (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k + ':' - ch(v[k], depth + 1) - soFar += ',' - } - soFar += '}' - } - ch(obj, 0) - return soFar -} - -exports.compare = -{ - // 'custom 2': function () { - // return custom(test, 2, 0) - // }, - // 'customWs 2': function () { - // return customWs(test, 2, 0) - // }, - 'JSON.stringify (guarded)': function () { - var seen = [] - return JSON.stringify(test, function (k, v) { - if (typeof v !== 'object' || !v) return v - if (seen.indexOf(v) !== -1) return undefined - seen.push(v) - return v - }) - }, - - 'flatten 10': function () { - return flatten(test, 10) - }, - - // 'flattenFE 10': function () { - // return flattenFE(test, 10) - // }, - - 'noCommas 10': function () { - return noCommas(test, 10) - }, - - 'sparse 10': function () { - return sparse(test, 10) - }, - - 'sparseFE 10': function () { - return sparseFE(test, 10) - }, - - 'sparseFE2 10': function () { - return sparseFE2(test, 10) - }, - - sigmund: function() { - return sigmund(test, 10) - }, - - - // 'util.inspect 1': function () { - // return util.inspect(test, false, 1, false) - // }, - // 'util.inspect undefined': function () { - // util.inspect(test) - // }, - // 'util.inspect 2': function () { - // util.inspect(test, false, 2, false) - // }, - // 'util.inspect 3': function () { - // util.inspect(test, false, 3, false) - // }, - // 'util.inspect 4': function () { - // util.inspect(test, false, 4, false) - // }, - // 'util.inspect Infinity': function () { - // util.inspect(test, false, Infinity, false) - // } -} - -/** results -**/ diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json deleted file mode 100644 index a1f755a7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "sigmund", - "version": "1.0.0", - "description": "Quick and dirty signatures for Objects.", - "main": "sigmund.js", - "directories": { - "test": "test" - }, - "dependencies": {}, - "devDependencies": { - "tap": "~0.3.0" - }, - "scripts": { - "test": "tap test/*.js", - "bench": "node bench.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/sigmund" - }, - "keywords": [ - "object", - "signature", - "key", - "data", - "psychoanalysis" - ], - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "license": "BSD", - "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n var cached = cache.get(key)\n if (cached) return cached)\n\n var result = expensiveCalculation(someObj)\n cache.set(key, result)\n return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you. In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions. For example, these objects\nhave the same signature:\n\n var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for. It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n", - "_id": "sigmund@1.0.0", - "dist": { - "shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296", - "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz" - }, - "_npmVersion": "1.1.48", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296", - "_from": "sigmund@~1.0.0", - "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz", - "bugs": { - "url": "https://github.com/isaacs/sigmund/issues" - }, - "homepage": "https://github.com/isaacs/sigmund" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js deleted file mode 100644 index 82c7ab8c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = sigmund -function sigmund (subject, maxSessions) { - maxSessions = maxSessions || 10; - var notes = []; - var analysis = ''; - var RE = RegExp; - - function psychoAnalyze (subject, session) { - if (session > maxSessions) return; - - if (typeof subject === 'function' || - typeof subject === 'undefined') { - return; - } - - if (typeof subject !== 'object' || !subject || - (subject instanceof RE)) { - analysis += subject; - return; - } - - if (notes.indexOf(subject) !== -1 || session === maxSessions) return; - - notes.push(subject); - analysis += '{'; - Object.keys(subject).forEach(function (issue, _, __) { - // pseudo-private values. skip those. - if (issue.charAt(0) === '_') return; - var to = typeof subject[issue]; - if (to === 'function' || to === 'undefined') return; - analysis += issue; - psychoAnalyze(subject[issue], session + 1); - }); - } - psychoAnalyze(subject, 0); - return analysis; -} - -// vim: set softtabstop=4 shiftwidth=4: diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js deleted file mode 100644 index 50c53a13..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js +++ /dev/null @@ -1,24 +0,0 @@ -var test = require('tap').test -var sigmund = require('../sigmund.js') - - -// occasionally there are duplicates -// that's an acceptable edge-case. JSON.stringify and util.inspect -// have some collision potential as well, though less, and collision -// detection is expensive. -var hash = '{abc/def/g{0h1i2{jkl' -var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} -var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} - -var obj3 = JSON.parse(JSON.stringify(obj1)) -obj3.c = /def/ -obj3.g[2].cycle = obj3 -var cycleHash = '{abc/def/g{0h1i2{jklcycle' - -test('basic', function (t) { - t.equal(sigmund(obj1), hash) - t.equal(sigmund(obj2), hash) - t.equal(sigmund(obj3), cycleHash) - t.end() -}) - diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json deleted file mode 100644 index 0fe147d6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me" - }, - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "0.3.0", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "minimatch.js", - "scripts": { - "test": "tap test/*.js" - }, - "engines": { - "node": "*" - }, - "dependencies": { - "lru-cache": "2", - "sigmund": "~1.0.0" - }, - "devDependencies": { - "tap": "" - }, - "license": { - "type": "MIT", - "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/minimatch/issues" - }, - "homepage": "https://github.com/isaacs/minimatch", - "_id": "minimatch@0.3.0", - "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", - "_from": "minimatch@0.3", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", - "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js deleted file mode 100644 index ae7ac73c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js +++ /dev/null @@ -1,399 +0,0 @@ -// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test -// -// TODO: Some of these tests do very bad things with backslashes, and will -// most likely fail badly on windows. They should probably be skipped. - -var tap = require("tap") - , globalBefore = Object.keys(global) - , mm = require("../") - , files = [ "a", "b", "c", "d", "abc" - , "abd", "abe", "bb", "bcd" - , "ca", "cb", "dd", "de" - , "bdir/", "bdir/cfile"] - , next = files.concat([ "a-b", "aXb" - , ".x", ".y" ]) - - -var patterns = - [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test" - , ["a*", ["a", "abc", "abd", "abe"]] - , ["X*", ["X*"], {nonull: true}] - - // allow null glob expansion - , ["X*", []] - - // isaacs: Slightly different than bash/sh/ksh - // \\* is not un-escaped to literal "*" in a failed match, - // but it does make it get treated as a literal star - , ["\\*", ["\\*"], {nonull: true}] - , ["\\**", ["\\**"], {nonull: true}] - , ["\\*\\*", ["\\*\\*"], {nonull: true}] - - , ["b*/", ["bdir/"]] - , ["c*", ["c", "ca", "cb"]] - , ["**", files] - - , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] - , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] - - , "legendary larry crashes bashes" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] - - , "character classes" - , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] - , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", - "bdir/", "ca", "cb", "dd", "de"]] - , ["a*[^c]", ["abd", "abe"]] - , function () { files.push("a-b", "aXb") } - , ["a[X-]b", ["a-b", "aXb"]] - , function () { files.push(".x", ".y") } - , ["[^a-c]*", ["d", "dd", "de"]] - , function () { files.push("a*b/", "a*b/ooo") } - , ["a\\*b/*", ["a*b/ooo"]] - , ["a\\*?/*", ["a*b/ooo"]] - , ["*\\\\!*", [], {null: true}, ["echo !7"]] - , ["*\\!*", ["echo !7"], null, ["echo !7"]] - , ["*.\\*", ["r.*"], null, ["r.*"]] - , ["a[b]c", ["abc"]] - , ["a[\\b]c", ["abc"]] - , ["a?c", ["abc"]] - , ["a\\*c", [], {null: true}, ["abc"]] - , ["", [""], { null: true }, [""]] - - , "http://www.opensource.apple.com/source/bash/bash-23/" + - "bash/tests/glob-test" - , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } - , ["*/man*/bash.*", ["man/man1/bash.1"]] - , ["man/man1/bash.1", ["man/man1/bash.1"]] - , ["a***c", ["abc"], null, ["abc"]] - , ["a*****?c", ["abc"], null, ["abc"]] - , ["?*****??", ["abc"], null, ["abc"]] - , ["*****??", ["abc"], null, ["abc"]] - , ["?*****?c", ["abc"], null, ["abc"]] - , ["?***?****c", ["abc"], null, ["abc"]] - , ["?***?****?", ["abc"], null, ["abc"]] - , ["?***?****", ["abc"], null, ["abc"]] - , ["*******c", ["abc"], null, ["abc"]] - , ["*******?", ["abc"], null, ["abc"]] - , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["[-abc]", ["-"], null, ["-"]] - , ["[abc-]", ["-"], null, ["-"]] - , ["\\", ["\\"], null, ["\\"]] - , ["[\\\\]", ["\\"], null, ["\\"]] - , ["[[]", ["["], null, ["["]] - , ["[", ["["], null, ["["]] - , ["[*", ["[abc"], null, ["[abc"]] - , "a right bracket shall lose its special meaning and\n" + - "represent itself in a bracket expression if it occurs\n" + - "first in the list. -- POSIX.2 2.8.3.2" - , ["[]]", ["]"], null, ["]"]] - , ["[]-]", ["]"], null, ["]"]] - , ["[a-\z]", ["p"], null, ["p"]] - , ["??**********?****?", [], { null: true }, ["abc"]] - , ["??**********?****c", [], { null: true }, ["abc"]] - , ["?************c****?****", [], { null: true }, ["abc"]] - , ["*c*?**", [], { null: true }, ["abc"]] - , ["a*****c*?**", [], { null: true }, ["abc"]] - , ["a********???*******", [], { null: true }, ["abc"]] - , ["[]", [], { null: true }, ["a"]] - , ["[abc", [], { null: true }, ["["]] - - , "nocase tests" - , ["XYZ", ["xYz"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["ab*", ["ABC"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - - // [ pattern, [matches], MM opts, files, TAP opts] - , "onestar/twostar" - , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] - , ["{/?,*}", ["/a", "bb"], {null: true} - , ["/a", "/b/b", "/a/b/c", "bb"]] - - , "dots should not match unless requested" - , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] - - // .. and . can only match patterns starting with ., - // even when options.dot is set. - , function () { - files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] - } - , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] - , ["a/*/b", ["a/c/b"], {dot:false}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] - - - // this also tests that changing the options needs - // to change the cache key, even if the pattern is - // the same! - , ["**", ["a/b","a/.d",".a/.d"], { dot: true } - , [ ".a/.d", "a/.d", "a/b"]] - - , "paren sets cannot contain slashes" - , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] - - // brace sets trump all else. - // - // invalid glob pattern. fails on bash4 and bsdglob. - // however, in this implementation, it's easier just - // to do the intuitive thing, and let brace-expansion - // actually come before parsing any extglob patterns, - // like the documentation seems to say. - // - // XXX: if anyone complains about this, either fix it - // or tell them to grow up and stop complaining. - // - // bash/bsdglob says this: - // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] - // but we do this instead: - , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] - - // test partial parsing in the presence of comment/negation chars - , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] - , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] - - // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. - , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] - , {} - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] - - - // crazy nested {,,} and *(||) tests. - , function () { - files = [ "a", "b", "c", "d" - , "ab", "ac", "ad" - , "bc", "cb" - , "bc,d", "c,db", "c,d" - , "d)", "(b|c", "*(b|c" - , "b|c", "b|cc", "cb|c" - , "x(a|b|c)", "x(a|c)" - , "(a|b|c)", "(a|c)"] - } - , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] - , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] - // a - // *(b|c) - // *(b|d) - , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] - , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] - - - // test various flag settings. - , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] - , { noext: true } ] - , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} - , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] - , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] - - - // begin channelling Boole and deMorgan... - , "negation tests" - , function () { - files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] - } - - // anything that is NOT a* matches. - , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] - - // anything that IS !a* matches. - , ["!a*", ["!ab", "!abc"], {nonegate: true}] - - // anything that IS a* matches - , ["!!a*", ["a!b"]] - - // anything that is NOT !a* matches - , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] - - // negation nestled within a pattern - , function () { - files = [ "foo.js" - , "foo.bar" - // can't match this one without negative lookbehind. - , "foo.js.js" - , "blar.js" - , "foo." - , "boo.js.boo" ] - } - , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] - - // https://github.com/isaacs/minimatch/issues/5 - , function () { - files = [ 'a/b/.x/c' - , 'a/b/.x/c/d' - , 'a/b/.x/c/d/e' - , 'a/b/.x' - , 'a/b/.x/' - , 'a/.x/b' - , '.x' - , '.x/' - , '.x/a' - , '.x/a/b' - , 'a/.x/b/.x/c' - , '.x/.x' ] - } - , ["**/.x/**", [ '.x/' - , '.x/a' - , '.x/a/b' - , 'a/.x/b' - , 'a/b/.x/' - , 'a/b/.x/c' - , 'a/b/.x/c/d' - , 'a/b/.x/c/d/e' ] ] - - ] - -var regexps = - [ '/^(?:(?=.)a[^/]*?)$/', - '/^(?:(?=.)X[^/]*?)$/', - '/^(?:(?=.)X[^/]*?)$/', - '/^(?:\\*)$/', - '/^(?:(?=.)\\*[^/]*?)$/', - '/^(?:\\*\\*)$/', - '/^(?:(?=.)b[^/]*?\\/)$/', - '/^(?:(?=.)c[^/]*?)$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', - '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/', - '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/', - '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/', - '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/', - '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/', - '/^(?:(?=.)a[^/]*?[^c])$/', - '/^(?:(?=.)a[X-]b)$/', - '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/', - '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/', - '/^(?:(?=.)a[b]c)$/', - '/^(?:(?=.)a[b]c)$/', - '/^(?:(?=.)a[^/]c)$/', - '/^(?:a\\*c)$/', - 'false', - '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/', - '/^(?:man\\/man1\\/bash\\.1)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[-abc])$/', - '/^(?:(?!\\.)(?=.)[abc-])$/', - '/^(?:\\\\)$/', - '/^(?:(?!\\.)(?=.)[\\\\])$/', - '/^(?:(?!\\.)(?=.)[\\[])$/', - '/^(?:\\[)$/', - '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[\\]])$/', - '/^(?:(?!\\.)(?=.)[\\]-])$/', - '/^(?:(?!\\.)(?=.)[a-z])$/', - '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:\\[\\])$/', - '/^(?:\\[abc)$/', - '/^(?:(?=.)XYZ)$/i', - '/^(?:(?=.)ab[^/]*?)$/i', - '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i', - '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/', - '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', - '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/', - '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', - '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/', - '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', - '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/', - '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/', - '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/', - '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/', - '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/', - '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/', - '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/', - '/^(?:(?=.)a[^/]b)$/', - '/^(?:(?=.)#[^/]*?)$/', - '/^(?!^(?:(?=.)a[^/]*?)$).*$/', - '/^(?:(?=.)\\!a[^/]*?)$/', - '/^(?:(?=.)a[^/]*?)$/', - '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ] -var re = 0; - -tap.test("basic tests", function (t) { - var start = Date.now() - - // [ pattern, [matches], MM opts, files, TAP opts] - patterns.forEach(function (c) { - if (typeof c === "function") return c() - if (typeof c === "string") return t.comment(c) - - var pattern = c[0] - , expect = c[1].sort(alpha) - , options = c[2] || {} - , f = c[3] || files - , tapOpts = c[4] || {} - - // options.debug = true - var m = new mm.Minimatch(pattern, options) - var r = m.makeRe() - var expectRe = regexps[re++] - tapOpts.re = String(r) || JSON.stringify(r) - tapOpts.files = JSON.stringify(f) - tapOpts.pattern = pattern - tapOpts.set = m.set - tapOpts.negated = m.negate - - var actual = mm.match(f, pattern, options) - actual.sort(alpha) - - t.equivalent( actual, expect - , JSON.stringify(pattern) + " " + JSON.stringify(expect) - , tapOpts ) - - t.equal(tapOpts.re, expectRe, tapOpts) - }) - - t.comment("time=" + (Date.now() - start) + "ms") - t.end() -}) - -tap.test("global leak test", function (t) { - var globalAfter = Object.keys(global) - t.equivalent(globalAfter, globalBefore, "no new globals, please") - t.end() -}) - -function alpha (a, b) { - return a > b ? 1 : -1 -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js deleted file mode 100644 index 7ee278a2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js +++ /dev/null @@ -1,33 +0,0 @@ -var tap = require("tap") - , minimatch = require("../") - -tap.test("brace expansion", function (t) { - // [ pattern, [expanded] ] - ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}" - , [ "abxy" - , "abxz" - , "acdxy" - , "acdxz" - , "acexy" - , "acexz" - , "afhxy" - , "afhxz" - , "aghxy" - , "aghxz" ] ] - , [ "a{1..5}b" - , [ "a1b" - , "a2b" - , "a3b" - , "a4b" - , "a5b" ] ] - , [ "a{b}c", ["a{b}c"] ] - ].forEach(function (tc) { - var p = tc[0] - , expect = tc[1] - t.equivalent(minimatch.braceExpand(p), expect, p) - }) - console.error("ending") - t.end() -}) - - diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js deleted file mode 100644 index 0fec4b0f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js +++ /dev/null @@ -1,14 +0,0 @@ -var Minimatch = require("../minimatch.js").Minimatch -var tap = require("tap") -tap.test("cache test", function (t) { - var mm1 = new Minimatch("a?b") - var mm2 = new Minimatch("a?b") - t.equal(mm1, mm2, "should get the same object") - // the lru should drop it after 100 entries - for (var i = 0; i < 100; i ++) { - new Minimatch("a"+i) - } - mm2 = new Minimatch("a?b") - t.notEqual(mm1, mm2, "cache should have dropped") - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js deleted file mode 100644 index 75e05712..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js +++ /dev/null @@ -1,274 +0,0 @@ -// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test -// -// TODO: Some of these tests do very bad things with backslashes, and will -// most likely fail badly on windows. They should probably be skipped. - -var tap = require("tap") - , globalBefore = Object.keys(global) - , mm = require("../") - , files = [ "a", "b", "c", "d", "abc" - , "abd", "abe", "bb", "bcd" - , "ca", "cb", "dd", "de" - , "bdir/", "bdir/cfile"] - , next = files.concat([ "a-b", "aXb" - , ".x", ".y" ]) - -tap.test("basic tests", function (t) { - var start = Date.now() - - // [ pattern, [matches], MM opts, files, TAP opts] - ; [ "http://www.bashcookbook.com/bashinfo" + - "/source/bash-1.14.7/tests/glob-test" - , ["a*", ["a", "abc", "abd", "abe"]] - , ["X*", ["X*"], {nonull: true}] - - // allow null glob expansion - , ["X*", []] - - // isaacs: Slightly different than bash/sh/ksh - // \\* is not un-escaped to literal "*" in a failed match, - // but it does make it get treated as a literal star - , ["\\*", ["\\*"], {nonull: true}] - , ["\\**", ["\\**"], {nonull: true}] - , ["\\*\\*", ["\\*\\*"], {nonull: true}] - - , ["b*/", ["bdir/"]] - , ["c*", ["c", "ca", "cb"]] - , ["**", files] - - , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] - , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] - - , "legendary larry crashes bashes" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] - - , "character classes" - , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] - , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", - "bdir/", "ca", "cb", "dd", "de"]] - , ["a*[^c]", ["abd", "abe"]] - , function () { files.push("a-b", "aXb") } - , ["a[X-]b", ["a-b", "aXb"]] - , function () { files.push(".x", ".y") } - , ["[^a-c]*", ["d", "dd", "de"]] - , function () { files.push("a*b/", "a*b/ooo") } - , ["a\\*b/*", ["a*b/ooo"]] - , ["a\\*?/*", ["a*b/ooo"]] - , ["*\\\\!*", [], {null: true}, ["echo !7"]] - , ["*\\!*", ["echo !7"], null, ["echo !7"]] - , ["*.\\*", ["r.*"], null, ["r.*"]] - , ["a[b]c", ["abc"]] - , ["a[\\b]c", ["abc"]] - , ["a?c", ["abc"]] - , ["a\\*c", [], {null: true}, ["abc"]] - , ["", [""], { null: true }, [""]] - - , "http://www.opensource.apple.com/source/bash/bash-23/" + - "bash/tests/glob-test" - , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } - , ["*/man*/bash.*", ["man/man1/bash.1"]] - , ["man/man1/bash.1", ["man/man1/bash.1"]] - , ["a***c", ["abc"], null, ["abc"]] - , ["a*****?c", ["abc"], null, ["abc"]] - , ["?*****??", ["abc"], null, ["abc"]] - , ["*****??", ["abc"], null, ["abc"]] - , ["?*****?c", ["abc"], null, ["abc"]] - , ["?***?****c", ["abc"], null, ["abc"]] - , ["?***?****?", ["abc"], null, ["abc"]] - , ["?***?****", ["abc"], null, ["abc"]] - , ["*******c", ["abc"], null, ["abc"]] - , ["*******?", ["abc"], null, ["abc"]] - , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["[-abc]", ["-"], null, ["-"]] - , ["[abc-]", ["-"], null, ["-"]] - , ["\\", ["\\"], null, ["\\"]] - , ["[\\\\]", ["\\"], null, ["\\"]] - , ["[[]", ["["], null, ["["]] - , ["[", ["["], null, ["["]] - , ["[*", ["[abc"], null, ["[abc"]] - , "a right bracket shall lose its special meaning and\n" + - "represent itself in a bracket expression if it occurs\n" + - "first in the list. -- POSIX.2 2.8.3.2" - , ["[]]", ["]"], null, ["]"]] - , ["[]-]", ["]"], null, ["]"]] - , ["[a-\z]", ["p"], null, ["p"]] - , ["??**********?****?", [], { null: true }, ["abc"]] - , ["??**********?****c", [], { null: true }, ["abc"]] - , ["?************c****?****", [], { null: true }, ["abc"]] - , ["*c*?**", [], { null: true }, ["abc"]] - , ["a*****c*?**", [], { null: true }, ["abc"]] - , ["a********???*******", [], { null: true }, ["abc"]] - , ["[]", [], { null: true }, ["a"]] - , ["[abc", [], { null: true }, ["["]] - - , "nocase tests" - , ["XYZ", ["xYz"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["ab*", ["ABC"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - - // [ pattern, [matches], MM opts, files, TAP opts] - , "onestar/twostar" - , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] - , ["{/?,*}", ["/a", "bb"], {null: true} - , ["/a", "/b/b", "/a/b/c", "bb"]] - - , "dots should not match unless requested" - , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] - - // .. and . can only match patterns starting with ., - // even when options.dot is set. - , function () { - files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] - } - , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] - , ["a/*/b", ["a/c/b"], {dot:false}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] - - - // this also tests that changing the options needs - // to change the cache key, even if the pattern is - // the same! - , ["**", ["a/b","a/.d",".a/.d"], { dot: true } - , [ ".a/.d", "a/.d", "a/b"]] - - , "paren sets cannot contain slashes" - , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] - - // brace sets trump all else. - // - // invalid glob pattern. fails on bash4 and bsdglob. - // however, in this implementation, it's easier just - // to do the intuitive thing, and let brace-expansion - // actually come before parsing any extglob patterns, - // like the documentation seems to say. - // - // XXX: if anyone complains about this, either fix it - // or tell them to grow up and stop complaining. - // - // bash/bsdglob says this: - // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] - // but we do this instead: - , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] - - // test partial parsing in the presence of comment/negation chars - , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] - , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] - - // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. - , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] - , {} - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] - - - // crazy nested {,,} and *(||) tests. - , function () { - files = [ "a", "b", "c", "d" - , "ab", "ac", "ad" - , "bc", "cb" - , "bc,d", "c,db", "c,d" - , "d)", "(b|c", "*(b|c" - , "b|c", "b|cc", "cb|c" - , "x(a|b|c)", "x(a|c)" - , "(a|b|c)", "(a|c)"] - } - , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] - , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] - // a - // *(b|c) - // *(b|d) - , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] - , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] - - - // test various flag settings. - , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] - , { noext: true } ] - , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} - , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] - , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] - - - // begin channelling Boole and deMorgan... - , "negation tests" - , function () { - files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] - } - - // anything that is NOT a* matches. - , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] - - // anything that IS !a* matches. - , ["!a*", ["!ab", "!abc"], {nonegate: true}] - - // anything that IS a* matches - , ["!!a*", ["a!b"]] - - // anything that is NOT !a* matches - , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] - - // negation nestled within a pattern - , function () { - files = [ "foo.js" - , "foo.bar" - // can't match this one without negative lookbehind. - , "foo.js.js" - , "blar.js" - , "foo." - , "boo.js.boo" ] - } - , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] - - ].forEach(function (c) { - if (typeof c === "function") return c() - if (typeof c === "string") return t.comment(c) - - var pattern = c[0] - , expect = c[1].sort(alpha) - , options = c[2] - , f = c[3] || files - , tapOpts = c[4] || {} - - // options.debug = true - var Class = mm.defaults(options).Minimatch - var m = new Class(pattern, {}) - var r = m.makeRe() - tapOpts.re = String(r) || JSON.stringify(r) - tapOpts.files = JSON.stringify(f) - tapOpts.pattern = pattern - tapOpts.set = m.set - tapOpts.negated = m.negate - - var actual = mm.match(f, pattern, options) - actual.sort(alpha) - - t.equivalent( actual, expect - , JSON.stringify(pattern) + " " + JSON.stringify(expect) - , tapOpts ) - }) - - t.comment("time=" + (Date.now() - start) + "ms") - t.end() -}) - -tap.test("global leak test", function (t) { - var globalAfter = Object.keys(global) - t.equivalent(globalAfter, globalBefore, "no new globals, please") - t.end() -}) - -function alpha (a, b) { - return a > b ? 1 : -1 -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js deleted file mode 100644 index 6676e262..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js +++ /dev/null @@ -1,8 +0,0 @@ -var test = require('tap').test -var minimatch = require('../') - -test('extglob ending with statechar', function(t) { - t.notOk(minimatch('ax', 'a?(b*)')) - t.ok(minimatch('ax', '?(a*|b)')) - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json deleted file mode 100644 index e7ec15f3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "name": "glob", - "description": "a little globber", - "version": "3.2.11", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "main": "glob.js", - "engines": { - "node": "*" - }, - "dependencies": { - "inherits": "2", - "minimatch": "0.3" - }, - "devDependencies": { - "tap": "~0.4.0", - "mkdirp": "0", - "rimraf": "1" - }, - "scripts": { - "test": "tap test/*.js", - "test-regen": "TEST_REGEN=1 node test/00-setup.js" - }, - "license": "BSD", - "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", - "bugs": { - "url": "https://github.com/isaacs/node-glob/issues" - }, - "homepage": "https://github.com/isaacs/node-glob", - "_id": "glob@3.2.11", - "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", - "_from": "glob@~3.2.9", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", - "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js deleted file mode 100644 index 245afafd..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/00-setup.js +++ /dev/null @@ -1,176 +0,0 @@ -// just a little pre-run script to set up the fixtures. -// zz-finish cleans it up - -var mkdirp = require("mkdirp") -var path = require("path") -var i = 0 -var tap = require("tap") -var fs = require("fs") -var rimraf = require("rimraf") - -var files = -[ "a/.abcdef/x/y/z/a" -, "a/abcdef/g/h" -, "a/abcfed/g/h" -, "a/b/c/d" -, "a/bc/e/f" -, "a/c/d/c/b" -, "a/cb/e/f" -] - -var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") -var symlinkFrom = "../.." - -files = files.map(function (f) { - return path.resolve(__dirname, f) -}) - -tap.test("remove fixtures", function (t) { - rimraf(path.resolve(__dirname, "a"), function (er) { - t.ifError(er, "remove fixtures") - t.end() - }) -}) - -files.forEach(function (f) { - tap.test(f, function (t) { - var d = path.dirname(f) - mkdirp(d, 0755, function (er) { - if (er) { - t.fail(er) - return t.bailout() - } - fs.writeFile(f, "i like tests", function (er) { - t.ifError(er, "make file") - t.end() - }) - }) - }) -}) - -if (process.platform !== "win32") { - tap.test("symlinky", function (t) { - var d = path.dirname(symlinkTo) - console.error("mkdirp", d) - mkdirp(d, 0755, function (er) { - t.ifError(er) - fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) { - t.ifError(er, "make symlink") - t.end() - }) - }) - }) -} - -;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { - w = "/tmp/glob-test/" + w - tap.test("create " + w, function (t) { - mkdirp(w, function (er) { - if (er) - throw er - t.pass(w) - t.end() - }) - }) -}) - - -// generate the bash pattern test-fixtures if possible -if (process.platform === "win32" || !process.env.TEST_REGEN) { - console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") - return -} - -var spawn = require("child_process").spawn; -var globs = - // put more patterns here. - // anything that would be directly in / should be in /tmp/glob-test - ["test/a/*/+(c|g)/./d" - ,"test/a/**/[cg]/../[cg]" - ,"test/a/{b,c,d,e,f}/**/g" - ,"test/a/b/**" - ,"test/**/g" - ,"test/a/abc{fed,def}/g/h" - ,"test/a/abc{fed/g,def}/**/" - ,"test/a/abc{fed/g,def}/**///**/" - ,"test/**/a/**/" - ,"test/+(a|b|c)/a{/,bc*}/**" - ,"test/*/*/*/f" - ,"test/**/f" - ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" - ,"{./*/*,/tmp/glob-test/*}" - ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! - ,"test/a/!(symlink)/**" - ] -var bashOutput = {} -var fs = require("fs") - -globs.forEach(function (pattern) { - tap.test("generate fixture " + pattern, function (t) { - var cmd = "shopt -s globstar && " + - "shopt -s extglob && " + - "shopt -s nullglob && " + - // "shopt >&2; " + - "eval \'for i in " + pattern + "; do echo $i; done\'" - var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) }) - var out = [] - cp.stdout.on("data", function (c) { - out.push(c) - }) - cp.stderr.pipe(process.stderr) - cp.on("close", function (code) { - out = flatten(out) - if (!out) - out = [] - else - out = cleanResults(out.split(/\r*\n/)) - - bashOutput[pattern] = out - t.notOk(code, "bash test should finish nicely") - t.end() - }) - }) -}) - -tap.test("save fixtures", function (t) { - var fname = path.resolve(__dirname, "bash-results.json") - var data = JSON.stringify(bashOutput, null, 2) + "\n" - fs.writeFile(fname, data, function (er) { - t.ifError(er) - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -function flatten (chunks) { - var s = 0 - chunks.forEach(function (c) { s += c.length }) - var out = new Buffer(s) - s = 0 - chunks.forEach(function (c) { - c.copy(out, s) - s += c.length - }) - - return out.toString().trim() -} - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js deleted file mode 100644 index 239ed1a9..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js +++ /dev/null @@ -1,63 +0,0 @@ -// basic test -// show that it does the same thing by default as the shell. -var tap = require("tap") -, child_process = require("child_process") -, bashResults = require("./bash-results.json") -, globs = Object.keys(bashResults) -, glob = require("../") -, path = require("path") - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -process.chdir(path.resolve(__dirname, "..")) - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -globs.forEach(function (pattern) { - var expect = bashResults[pattern] - // anything regarding the symlink thing will fail on windows, so just skip it - if (process.platform === "win32" && - expect.some(function (m) { - return /\/symlink\//.test(m) - })) - return - - tap.test(pattern, function (t) { - glob(pattern, function (er, matches) { - if (er) - throw er - - // sort and unmark, just to match the shell results - matches = cleanResults(matches) - - t.deepEqual(matches, expect, pattern) - t.end() - }) - }) - - tap.test(pattern + " sync", function (t) { - var matches = cleanResults(glob.sync(pattern)) - - t.deepEqual(matches, expect, "should match shell") - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') - }) -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json deleted file mode 100644 index 8051c723..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/bash-results.json +++ /dev/null @@ -1,351 +0,0 @@ -{ - "test/a/*/+(c|g)/./d": [ - "test/a/b/c/./d" - ], - "test/a/**/[cg]/../[cg]": [ - "test/a/abcdef/g/../g", - "test/a/abcfed/g/../g", - "test/a/b/c/../c", - "test/a/c/../c", - "test/a/c/d/c/../c", - "test/a/symlink/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c" - ], - "test/a/{b,c,d,e,f}/**/g": [], - "test/a/b/**": [ - "test/a/b", - "test/a/b/c", - "test/a/b/c/d" - ], - "test/**/g": [ - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/a/abc{fed,def}/g/h": [ - "test/a/abcdef/g/h", - "test/a/abcfed/g/h" - ], - "test/a/abc{fed/g,def}/**/": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/a/abc{fed/g,def}/**///**/": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/**/a/**/": [ - "test/a", - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/b", - "test/a/b/c", - "test/a/bc", - "test/a/bc/e", - "test/a/c", - "test/a/c/d", - "test/a/c/d/c", - "test/a/cb", - "test/a/cb/e", - "test/a/symlink", - "test/a/symlink/a", - "test/a/symlink/a/b", - "test/a/symlink/a/b/c", - "test/a/symlink/a/b/c/a", - "test/a/symlink/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b" - ], - "test/+(a|b|c)/a{/,bc*}/**": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcdef/g/h", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/abcfed/g/h" - ], - "test/*/*/*/f": [ - "test/a/bc/e/f", - "test/a/cb/e/f" - ], - "test/**/f": [ - "test/a/bc/e/f", - "test/a/cb/e/f" - ], - "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" - ], - "{./*/*,/tmp/glob-test/*}": [ - "./examples/g.js", - "./examples/usr-local.js", - "./node_modules/inherits", - "./node_modules/minimatch", - "./node_modules/mkdirp", - "./node_modules/rimraf", - "./node_modules/tap", - "./test/00-setup.js", - "./test/a", - "./test/bash-comparison.js", - "./test/bash-results.json", - "./test/cwd-test.js", - "./test/globstar-match.js", - "./test/mark.js", - "./test/new-glob-optional-options.js", - "./test/nocase-nomagic.js", - "./test/pause-resume.js", - "./test/readme-issue.js", - "./test/root-nomount.js", - "./test/root.js", - "./test/stat.js", - "./test/zz-cleanup.js", - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq" - ], - "{/tmp/glob-test/*,*}": [ - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq", - "examples", - "glob.js", - "LICENSE", - "node_modules", - "package.json", - "README.md", - "test" - ], - "test/a/!(symlink)/**": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcdef/g/h", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/abcfed/g/h", - "test/a/b", - "test/a/b/c", - "test/a/b/c/d", - "test/a/bc", - "test/a/bc/e", - "test/a/bc/e/f", - "test/a/c", - "test/a/c/d", - "test/a/c/d/c", - "test/a/c/d/c/b", - "test/a/cb", - "test/a/cb/e", - "test/a/cb/e/f" - ] -} diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js deleted file mode 100644 index 352c27ef..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/cwd-test.js +++ /dev/null @@ -1,55 +0,0 @@ -var tap = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -tap.test("changing cwd and searching for **/d", function (t) { - var glob = require('../') - var path = require('path') - t.test('.', function (t) { - glob('**/d', function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) - t.end() - }) - }) - - t.test('a', function (t) { - glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'b/c/d', 'c/d' ]) - t.end() - }) - }) - - t.test('a/b', function (t) { - glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) - t.end() - }) - }) - - t.test('a/b/', function (t) { - glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) - t.end() - }) - }) - - t.test('.', function (t) { - glob('**/d', {cwd: process.cwd()}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) - t.end() - }) - }) - - t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() - }) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js deleted file mode 100644 index 9b234fa2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/globstar-match.js +++ /dev/null @@ -1,19 +0,0 @@ -var Glob = require("../glob.js").Glob -var test = require('tap').test - -test('globstar should not have dupe matches', function(t) { - var pattern = 'a/**/[gh]' - var g = new Glob(pattern, { cwd: __dirname }) - var matches = [] - g.on('match', function(m) { - console.error('match %j', m) - matches.push(m) - }) - g.on('end', function(set) { - console.error('set', set) - matches = matches.sort() - set = set.sort() - t.same(matches, set, 'should have same set of matches') - t.end() - }) -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js deleted file mode 100644 index bf411c0e..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/mark.js +++ /dev/null @@ -1,118 +0,0 @@ -var test = require("tap").test -var glob = require('../') -process.chdir(__dirname) - -// expose timing issues -var lag = 5 -glob.Glob.prototype._stat = function(o) { return function(f, cb) { - var args = arguments - setTimeout(function() { - o.call(this, f, cb) - }.bind(this), lag += 5) -}}(glob.Glob.prototype._stat) - - -test("mark, with **", function (t) { - glob("a/*b*/**", {mark: true}, function (er, results) { - if (er) - throw er - var expect = - [ 'a/abcdef/', - 'a/abcdef/g/', - 'a/abcdef/g/h', - 'a/abcfed/', - 'a/abcfed/g/', - 'a/abcfed/g/h', - 'a/b/', - 'a/b/c/', - 'a/b/c/d', - 'a/bc/', - 'a/bc/e/', - 'a/bc/e/f', - 'a/cb/', - 'a/cb/e/', - 'a/cb/e/f' ] - - t.same(results, expect) - t.end() - }) -}) - -test("mark, no / on pattern", function (t) { - glob("a/*", {mark: true}, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - - if (process.platform !== "win32") - expect.push('a/symlink/') - - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) - -test("mark=false, no / on pattern", function (t) { - glob("a/*", function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef', - 'a/abcfed', - 'a/b', - 'a/bc', - 'a/c', - 'a/cb' ] - - if (process.platform !== "win32") - expect.push('a/symlink') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /[^\/]$/) - }) -}) - -test("mark=true, / on pattern", function (t) { - glob("a/*/", {mark: true}, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) - -test("mark=false, / on pattern", function (t) { - glob("a/*/", function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js deleted file mode 100644 index 3e7dc5ac..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js +++ /dev/null @@ -1,10 +0,0 @@ -var Glob = require('../glob.js').Glob; -var test = require('tap').test; - -test('new glob, with cb, and no options', function (t) { - new Glob(__filename, function(er, results) { - if (er) throw er; - t.same(results, [__filename]); - t.end(); - }); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js deleted file mode 100644 index 2503f231..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js +++ /dev/null @@ -1,113 +0,0 @@ -var fs = require('fs'); -var test = require('tap').test; -var glob = require('../'); - -test('mock fs', function(t) { - var stat = fs.stat - var statSync = fs.statSync - var readdir = fs.readdir - var readdirSync = fs.readdirSync - - function fakeStat(path) { - var ret - switch (path.toLowerCase()) { - case '/tmp': case '/tmp/': - ret = { isDirectory: function() { return true } } - break - case '/tmp/a': - ret = { isDirectory: function() { return false } } - break - } - return ret - } - - fs.stat = function(path, cb) { - var f = fakeStat(path); - if (f) { - process.nextTick(function() { - cb(null, f) - }) - } else { - stat.call(fs, path, cb) - } - } - - fs.statSync = function(path) { - return fakeStat(path) || statSync.call(fs, path) - } - - function fakeReaddir(path) { - var ret - switch (path.toLowerCase()) { - case '/tmp': case '/tmp/': - ret = [ 'a', 'A' ] - break - case '/': - ret = ['tmp', 'tMp', 'tMP', 'TMP'] - } - return ret - } - - fs.readdir = function(path, cb) { - var f = fakeReaddir(path) - if (f) - process.nextTick(function() { - cb(null, f) - }) - else - readdir.call(fs, path, cb) - } - - fs.readdirSync = function(path) { - return fakeReaddir(path) || readdirSync.call(fs, path) - } - - t.pass('mocked') - t.end() -}) - -test('nocase, nomagic', function(t) { - var n = 2 - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - glob('/tmp/a', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - if (--n === 0) t.end() - }) - glob('/tmp/A', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - if (--n === 0) t.end() - }) -}) - -test('nocase, with some magic', function(t) { - t.plan(2) - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - }) - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - }) -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js deleted file mode 100644 index e1ffbab1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/pause-resume.js +++ /dev/null @@ -1,73 +0,0 @@ -// show that no match events happen while paused. -var tap = require("tap") -, child_process = require("child_process") -// just some gnarly pattern with lots of matches -, pattern = "test/a/!(symlink)/**" -, bashResults = require("./bash-results.json") -, patterns = Object.keys(bashResults) -, glob = require("../") -, Glob = glob.Glob -, path = require("path") - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -process.chdir(path.resolve(__dirname, "..")) - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -var globResults = [] -tap.test("use a Glob object, and pause/resume it", function (t) { - var g = new Glob(pattern) - , paused = false - , res = [] - , expect = bashResults[pattern] - - g.on("pause", function () { - console.error("pause") - }) - - g.on("resume", function () { - console.error("resume") - }) - - g.on("match", function (m) { - t.notOk(g.paused, "must not be paused") - globResults.push(m) - g.pause() - t.ok(g.paused, "must be paused") - setTimeout(g.resume.bind(g), 10) - }) - - g.on("end", function (matches) { - t.pass("reached glob end") - globResults = cleanResults(globResults) - matches = cleanResults(matches) - t.deepEqual(matches, globResults, - "end event matches should be the same as match events") - - t.deepEqual(matches, expect, - "glob matches should be the same as bash results") - - t.end() - }) -}) - diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js deleted file mode 100644 index 0b4e0be2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/readme-issue.js +++ /dev/null @@ -1,36 +0,0 @@ -var test = require("tap").test -var glob = require("../") - -var mkdirp = require("mkdirp") -var fs = require("fs") -var rimraf = require("rimraf") -var dir = __dirname + "/package" - -test("setup", function (t) { - mkdirp.sync(dir) - fs.writeFileSync(dir + "/package.json", "{}", "ascii") - fs.writeFileSync(dir + "/README", "x", "ascii") - t.pass("setup done") - t.end() -}) - -test("glob", function (t) { - var opt = { - cwd: dir, - nocase: true, - mark: true - } - - glob("README?(.*)", opt, function (er, files) { - if (er) - throw er - t.same(files, ["README"]) - t.end() - }) -}) - -test("cleanup", function (t) { - rimraf.sync(dir) - t.pass("clean") - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js deleted file mode 100644 index 3ac5979b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root-nomount.js +++ /dev/null @@ -1,39 +0,0 @@ -var tap = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -tap.test("changing root and searching for /b*/**", function (t) { - var glob = require('../') - var path = require('path') - t.test('.', function (t) { - glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, []) - t.end() - }) - }) - - t.test('a', function (t) { - glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - t.end() - }) - }) - - t.test('root=a, cwd=a/b', function (t) { - glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - t.end() - }) - }) - - t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() - }) - - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js deleted file mode 100644 index 95c23f99..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/root.js +++ /dev/null @@ -1,46 +0,0 @@ -var t = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -var glob = require('../') -var path = require('path') - -t.test('.', function (t) { - glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { - t.ifError(er) - t.like(matches, []) - t.end() - }) -}) - - -t.test('a', function (t) { - console.error("root=" + path.resolve('a')) - glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { - t.ifError(er) - var wanted = [ - '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' - ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - }) - - t.like(matches, wanted) - t.end() - }) -}) - -t.test('root=a, cwd=a/b', function (t) { - glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - })) - t.end() - }) -}) - -t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js deleted file mode 100644 index 62917114..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/stat.js +++ /dev/null @@ -1,32 +0,0 @@ -var glob = require('../') -var test = require('tap').test -var path = require('path') - -test('stat all the things', function(t) { - var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname }) - var matches = [] - g.on('match', function(m) { - matches.push(m) - }) - var stats = [] - g.on('stat', function(m) { - stats.push(m) - }) - g.on('end', function(eof) { - stats = stats.sort() - matches = matches.sort() - eof = eof.sort() - t.same(stats, matches) - t.same(eof, matches) - var cache = Object.keys(this.statCache) - t.same(cache.map(function (f) { - return path.relative(__dirname, f) - }).sort(), matches) - - cache.forEach(function(c) { - t.equal(typeof this.statCache[c], 'object') - }, this) - - t.end() - }) -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js deleted file mode 100644 index e085f0fa..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js +++ /dev/null @@ -1,11 +0,0 @@ -// remove the fixtures -var tap = require("tap") -, rimraf = require("rimraf") -, path = require("path") - -tap.test("cleanup fixtures", function (t) { - rimraf(path.resolve(__dirname, "a"), function (er) { - t.ifError(er, "removed") - t.end() - }) -}) diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt deleted file mode 100644 index 49869bba..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright 2012-2013 The Dojo Foundation -Based on Underscore.js 1.5.2, copyright 2009-2013 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. \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md deleted file mode 100644 index 6f9598e8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Lo-Dash v2.4.1 -A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features). - -## Download - -Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds. - -* Modern builds perfect for newer browsers/environments:
    -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js) - -* Compatibility builds for older environment support too:
    -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js) - -* Underscore builds to use as a drop-in replacement:
    -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js) - -CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed. - -Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method. - -## Dive in - -There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).
    -Check out
    DevDocs as a fast, organized, & searchable interface for our documentation. - -The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
    -A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). - -## Features *not* in Underscore - - * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) - * [_(…)](http://lodash.com/docs#_) supports intuitive chaining - * [_.at](http://lodash.com/docs#at) for cherry-picking collection values - * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazyâ€*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods - * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects - * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects - * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions - * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` - * [_.create](http://lodash.com/docs#create) for easier object inheritance - * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins - * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions - * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control - * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys - * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early - * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties - * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties - * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object` - * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object - * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions - * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend) - * [_.noop](http://lodash.com/docs#noop) for function placeholders - * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative - * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior - * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays - * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers - * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking - * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties - * [_.support](http://lodash.com/docs#support) for flagging environment features - * [_.template](http://lodash.com/docs#template) supports [*“importsâ€*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) - * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects - * [_.where](http://lodash.com/docs#where) supports deep object comparisons - * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union) - * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values - * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), & - [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks - * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), & - [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings - * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), & - [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluckâ€* & *“_.whereâ€* shorthands - * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), & - [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods - -## Resources - - * Podcasts - - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) - - * Posts - - [Say “Hello†to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) - - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) - - * Videos - - [Introduction](https://vimeo.com/44154599) - - [Origins](https://vimeo.com/44154600) - - [Optimizations & builds](https://vimeo.com/44154601) - - [Native method use](https://vimeo.com/48576012) - - [Testing](https://vimeo.com/45865290) - - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) - - A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). - -## Support - -Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
    -Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash). - -Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
    -[![Sauce Labs](http://lodash.com/_img/sauce.png)](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More") - -## Installation & usage - -In browsers: - -```html - -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm i --save lodash - -{sudo} npm i -g lodash -npm ln lodash -``` - -In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): - -```js -var _ = require('lodash'); -// or as Underscore -var _ = require('lodash/dist/lodash.underscore'); -``` - -**Notes:** - * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL - * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader: - -```js -require({ - 'packages': [ - { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } - ] -}, -['lodash'], function(_) { - console.log(_.VERSION); -}); -``` - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 23798ba8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,7157 +0,0 @@ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; - - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = {}; - - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; - - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; - - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; - - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + - - // line terminators - '\n\r\u2028\u2029' + - - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowedProps = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - errorClass = '[object Error]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; - - /** Used as the data object for `iteratorTemplate` */ - var iteratorData = { - 'args': '', - 'array': null, - 'bottom': '', - 'firstArg': '', - 'init': '', - 'keys': null, - 'loop': '', - 'shadowedProps': null, - 'support': null, - 'top': '', - 'useHas': false - }; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; - - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; - } - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } - - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; - - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); - - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; - } - } - } - - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; - - while (++index < length) { - var value = ac[index], - other = bc[index]; - - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; - - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; - - while (++index < length) { - result.push(array[index]); - } - return result; - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } - - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); - } - } - - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); - } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); - } - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ - var arrayRef = []; - - /** Used for native method references */ - var errorProto = Error.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; - - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); - - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; - - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to avoid iterating non-enumerable properties in IE < 9 */ - var nonEnumProps = {}; - nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; - nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; - nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; - nonEnumProps[objectClass] = { 'constructor': true }; - - (function() { - var length = shadowedProps.length; - while (length--) { - var key = shadowedProps[length]; - for (var className in nonEnumProps) { - if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { - nonEnumProps[className][key] = false; - } - } - } - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; - - /** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function() { - var ctor = function() { this.x = 1; }, - object = { '0': 1, 'length': 1 }, - props = []; - - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var key in new ctor) { props.push(key); } - for (key in arguments) { } - - /** - * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsClass = toString.call(arguments) == argsClass; - - /** - * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). - * - * @memberOf _.support - * @type boolean - */ - support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); - - /** - * Detect if `name` or `message` properties of `Error.prototype` are - * enumerable by default. (IE < 9, Safari < 5.1) - * - * @memberOf _.support - * @type boolean - */ - support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); - - /** - * Detect if `prototype` properties are enumerable by default. - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - * - * @memberOf _.support - * @type boolean - */ - support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if `arguments` object indexes are non-enumerable - * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumArgs = key != 0; - - /** - * Detect if properties shadowing those on `Object.prototype` are non-enumerable. - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumShadows = !/valueOf/.test(props); - - /** - * Detect if own properties are iterated after inherited properties (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.ownLast = props[0] != 'x'; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); - - /** - * Detect lack of support for accessing string characters by index. - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - * - * @memberOf _.support - * @type boolean - */ - support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) - * and that the JS engine errors when attempting to coerce an object to - * a string without a `toString` function. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); - } catch(e) { - support.nodeClass = true; - } - }(1)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Object} data The data object used to populate the text. - * @returns {string} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg) + - ', result = ' + - (obj.init) + - ';\nif (!iterable) return result;\n' + - (obj.top) + - ';'; - if (obj.array) { - __p += '\nvar length = iterable.length; index = -1;\nif (' + - (obj.array) + - ') { '; - if (support.unindexedChars) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } - __p += '\n while (++index < length) {\n ' + - (obj.loop) + - ';\n }\n}\nelse { '; - } else if (support.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop) + - ';\n }\n } else { '; - } - - if (support.enumPrototypes) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } - - if (support.enumErrorProps) { - __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; - } - - var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } - - if (obj.useHas && obj.keys) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; - if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - } else { - __p += '\n for (index in iterable) {\n'; - if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - if (support.nonEnumShadows) { - __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; - for (k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowedProps[k]) + - '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; - if (!obj.useHas) { - __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; - } - __p += ') {\n ' + - (obj.loop) + - ';\n } '; - } - __p += '\n } '; - } - - } - - if (obj.array || support.nonEnumArgs) { - __p += '\n}'; - } - __p += - (obj.bottom) + - ';\nreturn result'; - - return __p - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; - } - else { - result = isArr ? slice(value) : assign({}, value); - } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - // exit for shallow clone - if (!isDeep) { - return result; - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); - }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } - - /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. - */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; - - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(values); - } - return result; - } - - /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. - */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - } - stackA.pop(); - stackB.pop(); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - - /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. - * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. - */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; - - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; - - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; - } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; - } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; - } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); - } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); - } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {...Object} [options] The compile options object(s). - * @param {string} [options.array] Code to determine if the iterable is an array or array-like. - * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. - * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. - * @param {string} [options.args] A comma separated string of iteration function arguments. - * @param {string} [options.top] Code to execute before the iteration branches. - * @param {string} [options.loop] Code to execute in the object loop. - * @param {string} [options.bottom] Code to execute after the iteration branches. - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - // data properties - iteratorData.shadowedProps = shadowedProps; - - // iterator options - iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; - iteratorData.init = 'iterable'; - iteratorData.useHas = true; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - iteratorData[key] = object[key]; - } - } - var args = iteratorData.args; - iteratorData.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + - 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + - 'objectTypes, nonEnumProps, stringClass, stringProto, toString', - 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' - ); - - // return the compiled function - return factory( - baseCreateCallback, errorClass, errorProto, hasOwnProperty, - indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, - objectTypes, nonEnumProps, stringClass, stringProto, toString - ); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || - (!support.argsClass && isArguments(value)) || - (!support.nodeClass && isNode(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (support.ownLast) { - forIn(value, function(value, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (!support.argsClass) { - isArguments = function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; - }; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = createIterator({ - 'args': 'object', - 'init': '[]', - 'top': 'if (!(objectTypes[typeof object])) return result', - 'loop': 'result.push(index)' - }); - - /** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", - 'array': "typeof length == 'number'", - 'keys': keys, - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'keys': keys, - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'array': false - }; - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the callback for each - * element in the collection. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createIterator(eachIteratorOptions); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; - } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } - * }; - * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' - * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' - */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } - * }; - * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' - * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' - */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' - */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); - - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; - } - } - return object; - } - - /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } - } - return object; - } - - /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value && value.nodeType === 1 || false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - (support.argsClass ? className == argsClass : isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value == 'function' && toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; - } - - /** - * Checks if `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * _.isPlainObject(new Shape); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/fred/); - * // => true - */ - function isRegExp(value) { - return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('fred'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } - */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } - * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } - */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } - } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? baseEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); - } - return accumulator; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.contains('pebbles', 'eb'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - baseEach(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - - /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } - * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } - */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - } - - /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 - */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - baseEach(collection, callback, thisArg); - } - return collection; - } - - /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' - */ - function forEachRight(collection, callback, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (support.unindexedChars && isString(collection)) { - iterable = collection.split(''); - } - baseEach(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(iterable[key], key, collection); - }); - } - return collection; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = lodash.createCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; - * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the collection. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] - */ - var pluck = map; - - /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Retrieves a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } else if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] - * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); - } - releaseObject(object); - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (support.unindexedChars && isString(collection)) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] - * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; - * }); - * // => 2 - * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 - */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 - * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 - */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] - */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] - */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; - } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] - */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; - - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); - } - } - releaseArray(caches); - releaseArray(seen); - return result; - } - - /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. - * - * @static - * @memberOf _ - * @category Arrays - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); - * - * console.log(array); - * // => [1, 3, 5] - * - * console.log(evens); - * // => [2, 4, 6] - */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); - } - - /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); - } - - /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. - * - * @static - * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed - */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' - * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; - * - * func(); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } - - /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; - * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; - * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' - */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. - * @example - * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 - * - * curried(1, 2)(3); - * // => 6 - * - * curried(1, 2, 3); - * // => 6 - */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); - * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); - * - * // ensure `batchLog` is executed once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * source.addEventListener('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * }, false); - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - wait = nativeMax(0, wait) || 0; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); - trailing = 'trailing' in options ? options.trailing : trailing; - } - var delayed = function() { - var remaining = wait - (now() - stamp); - if (remaining <= 0) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - }; - - var maxDelayed = function() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - }; - - return function() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - }; - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay execution. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it will be used to determine the cache key for storing the result - * based on the arguments provided to the memoized function. By default, the - * first argument provided to the memoized function is used as the cache key. - * The `func` is executed with the `this` binding of the memoized function. - * The result cache is exposed as the `cache` property on the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - * - * fibonacci(9) - * // => 34 - * - * var data = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // modifying the result cache - * var get = _.memoize(function(name) { return data[name]; }, _.identity); - * get('pebbles'); - * // => { 'name': 'pebbles', 'age': 1 } - * - * get.cache.pebbles.name = 'penelope'; - * get('pebbles'); - * // => { 'name': 'penelope', 'age': 1 } - */ - function memoize(func, resolver) { - if (!isFunction(func)) { - throw new TypeError; - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; - - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - } - memoized.cache = {}; - return memoized; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those provided to the new function. This - * method is similar to `_.bind` except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('fred'); - * // => 'hi fred' - */ - function partial(func) { - return createWrapper(func, 16, slice(arguments, 1)); - } - - /** - * This method is like `_.partial` except that `partial` arguments are - * appended to those provided to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createWrapper(func, 32, null, slice(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` function - * at most once per every `wait` milliseconds. Provide an options object to - * indicate that `func` should be invoked on the leading and/or trailing edge - * of the `wait` timeout. Subsequent calls to the throttled function will - * return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle executions to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - * - * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? options.leading : leading; - trailing = 'trailing' in options ? options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = wait; - debounceOptions.trailing = trailing; - - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Additional arguments provided to the function are appended - * to those provided to the wrapper function. The wrapper is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

    ' + func(text) + '

    '; - * }); - * - * p('Fred, Wilma, & Pebbles'); - * // => '

    Fred, Wilma, & Pebbles

    ' - */ - function wrap(value, wrapper) { - return createWrapper(wrapper, 16, [value]); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. - * @example - * - * var object = { 'name': 'fred' }; - * var getter = _.constant(object); - * getter() === object; - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ - function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; - - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } - } - return result; - }; - } - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} string The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('Fred, Wilma, & Pebbles'); - * // => 'Fred, Wilma, & Pebbles' - */ - function escape(string) { - return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds function properties of a source object to the destination object. - * If `object` is a function methods will be added to its prototype as well. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Function|Object} [object=lodash] object The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options] The options object. - * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. - * @example - * - * function capitalize(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * - * _.mixin({ 'capitalize': capitalize }); - * _.capitalize('fred'); - * // => 'Fred' - * - * _('fred').capitalize().value(); - * // => 'Fred' - * - * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); - * _('fred').capitalize(); - * // => 'Fred' - */ - function mixin(object, source, options) { - var chain = true, - methodNames = source && functions(source); - - if (!source || (!options && !methodNames.length)) { - if (options == null) { - options = source; - } - ctor = lodashWrapper; - source = object; - object = lodash; - methodNames = functions(source); - } - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - var ctor = object, - isFunc = isFunction(ctor); - - forEach(methodNames, function(methodName) { - var func = object[methodName] = source[methodName]; - if (isFunc) { - ctor.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new ctor(result); - result.__chain__ = chainAll; - } - return result; - }; - } - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - context._ = oldDash; - return this; - } - - /** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ - function noop() { - // no operation performed - } - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var stamp = _.now(); - * _.defer(function() { console.log(_.now() - stamp); }); - * // => logs the number of milliseconds it took for the deferred function to be called - */ - var now = isNative(now = Date.now) && now || function() { - return new Date().getTime(); - }; - - /** - * Converts the given value into an integer of the specified radix. - * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the - * `value` is a hexadecimal, in which case a `radix` of `16` is used. - * - * Note: This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See http://es5.github.io/#E. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} value The value to parse. - * @param {number} [radix] The radix used to interpret the value to parse. - * @returns {number} Returns the new integer value. - * @example - * - * _.parseInt('08'); - * // => 8 - */ - var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` - return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); - }; - - /** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example - * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; - * - * var getName = _.property('name'); - * - * _.map(characters, getName); - * // => ['barney', 'fred'] - * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] - */ - function property(key) { - return function(object) { - return object[key]; - }; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number will be - * returned. If `floating` is truey or either `min` or `max` are floats a - * floating-point number will be returned instead of an integer. - * - * @static - * @memberOf _ - * @category Utilities - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating=false] Specify returning a floating-point number. - * @returns {number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (typeof min == 'boolean' && noMax) { - floating = min; - min = 1; - } - else if (!noMax && typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); - } - return baseRandom(min, max); - } - - /** - * Resolves the value of property `key` on `object`. If `key` is a function - * it will be invoked with the `this` binding of `object` and its result returned, - * else the property value is returned. If `object` is falsey then `undefined` - * is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to resolve. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, key) { - if (object) { - var value = object[key]; - return isFunction(value) ? object[key]() : value; - } - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * For more information on precompiling templates see: - * http://lodash.com/custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} text The template text. - * @param {Object} data The data object used to populate the text. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as local variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [sourceURL] The sourceURL of the template's compiled source. - * @param {string} [variable] The data object variable name. - * @returns {Function|string} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': ' -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm i --save lodash - -{sudo} npm i -g lodash -npm ln lodash -``` - -In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): - -```js -var _ = require('lodash'); -// or as Underscore -var _ = require('lodash/dist/lodash.underscore'); -``` - -**Notes:** - * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL - * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader: - -```js -require({ - 'packages': [ - { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } - ] -}, -['lodash'], function(_) { - console.log(_.VERSION); -}); -``` - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 23798ba8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,7157 +0,0 @@ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; - - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = {}; - - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; - - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; - - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; - - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + - - // line terminators - '\n\r\u2028\u2029' + - - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowedProps = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - errorClass = '[object Error]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; - - /** Used as the data object for `iteratorTemplate` */ - var iteratorData = { - 'args': '', - 'array': null, - 'bottom': '', - 'firstArg': '', - 'init': '', - 'keys': null, - 'loop': '', - 'shadowedProps': null, - 'support': null, - 'top': '', - 'useHas': false - }; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; - - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; - } - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } - - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; - - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); - - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; - } - } - } - - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; - - while (++index < length) { - var value = ac[index], - other = bc[index]; - - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; - - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; - - while (++index < length) { - result.push(array[index]); - } - return result; - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } - - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); - } - } - - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); - } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); - } - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ - var arrayRef = []; - - /** Used for native method references */ - var errorProto = Error.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; - - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); - - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; - - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to avoid iterating non-enumerable properties in IE < 9 */ - var nonEnumProps = {}; - nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; - nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; - nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; - nonEnumProps[objectClass] = { 'constructor': true }; - - (function() { - var length = shadowedProps.length; - while (length--) { - var key = shadowedProps[length]; - for (var className in nonEnumProps) { - if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { - nonEnumProps[className][key] = false; - } - } - } - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; - - /** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function() { - var ctor = function() { this.x = 1; }, - object = { '0': 1, 'length': 1 }, - props = []; - - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var key in new ctor) { props.push(key); } - for (key in arguments) { } - - /** - * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsClass = toString.call(arguments) == argsClass; - - /** - * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). - * - * @memberOf _.support - * @type boolean - */ - support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); - - /** - * Detect if `name` or `message` properties of `Error.prototype` are - * enumerable by default. (IE < 9, Safari < 5.1) - * - * @memberOf _.support - * @type boolean - */ - support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); - - /** - * Detect if `prototype` properties are enumerable by default. - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - * - * @memberOf _.support - * @type boolean - */ - support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if `arguments` object indexes are non-enumerable - * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumArgs = key != 0; - - /** - * Detect if properties shadowing those on `Object.prototype` are non-enumerable. - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumShadows = !/valueOf/.test(props); - - /** - * Detect if own properties are iterated after inherited properties (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.ownLast = props[0] != 'x'; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); - - /** - * Detect lack of support for accessing string characters by index. - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - * - * @memberOf _.support - * @type boolean - */ - support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) - * and that the JS engine errors when attempting to coerce an object to - * a string without a `toString` function. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); - } catch(e) { - support.nodeClass = true; - } - }(1)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Object} data The data object used to populate the text. - * @returns {string} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg) + - ', result = ' + - (obj.init) + - ';\nif (!iterable) return result;\n' + - (obj.top) + - ';'; - if (obj.array) { - __p += '\nvar length = iterable.length; index = -1;\nif (' + - (obj.array) + - ') { '; - if (support.unindexedChars) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } - __p += '\n while (++index < length) {\n ' + - (obj.loop) + - ';\n }\n}\nelse { '; - } else if (support.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop) + - ';\n }\n } else { '; - } - - if (support.enumPrototypes) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } - - if (support.enumErrorProps) { - __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; - } - - var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } - - if (obj.useHas && obj.keys) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; - if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - } else { - __p += '\n for (index in iterable) {\n'; - if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - if (support.nonEnumShadows) { - __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; - for (k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowedProps[k]) + - '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; - if (!obj.useHas) { - __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; - } - __p += ') {\n ' + - (obj.loop) + - ';\n } '; - } - __p += '\n } '; - } - - } - - if (obj.array || support.nonEnumArgs) { - __p += '\n}'; - } - __p += - (obj.bottom) + - ';\nreturn result'; - - return __p - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; - } - else { - result = isArr ? slice(value) : assign({}, value); - } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - // exit for shallow clone - if (!isDeep) { - return result; - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); - }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } - - /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. - */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; - - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(values); - } - return result; - } - - /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. - */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - } - stackA.pop(); - stackB.pop(); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - - /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. - * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. - */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; - - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; - - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; - } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; - } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; - } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); - } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); - } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {...Object} [options] The compile options object(s). - * @param {string} [options.array] Code to determine if the iterable is an array or array-like. - * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. - * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. - * @param {string} [options.args] A comma separated string of iteration function arguments. - * @param {string} [options.top] Code to execute before the iteration branches. - * @param {string} [options.loop] Code to execute in the object loop. - * @param {string} [options.bottom] Code to execute after the iteration branches. - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - // data properties - iteratorData.shadowedProps = shadowedProps; - - // iterator options - iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; - iteratorData.init = 'iterable'; - iteratorData.useHas = true; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - iteratorData[key] = object[key]; - } - } - var args = iteratorData.args; - iteratorData.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + - 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + - 'objectTypes, nonEnumProps, stringClass, stringProto, toString', - 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' - ); - - // return the compiled function - return factory( - baseCreateCallback, errorClass, errorProto, hasOwnProperty, - indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, - objectTypes, nonEnumProps, stringClass, stringProto, toString - ); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || - (!support.argsClass && isArguments(value)) || - (!support.nodeClass && isNode(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (support.ownLast) { - forIn(value, function(value, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (!support.argsClass) { - isArguments = function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; - }; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = createIterator({ - 'args': 'object', - 'init': '[]', - 'top': 'if (!(objectTypes[typeof object])) return result', - 'loop': 'result.push(index)' - }); - - /** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", - 'array': "typeof length == 'number'", - 'keys': keys, - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'keys': keys, - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'array': false - }; - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the callback for each - * element in the collection. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createIterator(eachIteratorOptions); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; - } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } - * }; - * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' - * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' - */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } - * }; - * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' - * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' - */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' - */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); - - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; - } - } - return object; - } - - /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } - } - return object; - } - - /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value && value.nodeType === 1 || false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - (support.argsClass ? className == argsClass : isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value == 'function' && toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; - } - - /** - * Checks if `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * _.isPlainObject(new Shape); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/fred/); - * // => true - */ - function isRegExp(value) { - return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('fred'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } - */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } - * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } - */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } - } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? baseEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); - } - return accumulator; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.contains('pebbles', 'eb'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - baseEach(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - - /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } - * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } - */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - } - - /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 - */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - baseEach(collection, callback, thisArg); - } - return collection; - } - - /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' - */ - function forEachRight(collection, callback, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (support.unindexedChars && isString(collection)) { - iterable = collection.split(''); - } - baseEach(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(iterable[key], key, collection); - }); - } - return collection; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = lodash.createCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; - * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the collection. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] - */ - var pluck = map; - - /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Retrieves a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } else if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] - * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); - } - releaseObject(object); - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (support.unindexedChars && isString(collection)) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] - * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; - * }); - * // => 2 - * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 - */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 - * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 - */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] - */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] - */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; - } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] - */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; - - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); - } - } - releaseArray(caches); - releaseArray(seen); - return result; - } - - /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. - * - * @static - * @memberOf _ - * @category Arrays - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); - * - * console.log(array); - * // => [1, 3, 5] - * - * console.log(evens); - * // => [2, 4, 6] - */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); - } - - /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); - } - - /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. - * - * @static - * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed - */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' - * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; - * - * func(); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } - - /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; - * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; - * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' - */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. - * @example - * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 - * - * curried(1, 2)(3); - * // => 6 - * - * curried(1, 2, 3); - * // => 6 - */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); - * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); - * - * // ensure `batchLog` is executed once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * source.addEventListener('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * }, false); - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - wait = nativeMax(0, wait) || 0; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); - trailing = 'trailing' in options ? options.trailing : trailing; - } - var delayed = function() { - var remaining = wait - (now() - stamp); - if (remaining <= 0) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - }; - - var maxDelayed = function() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - }; - - return function() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - }; - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay execution. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it will be used to determine the cache key for storing the result - * based on the arguments provided to the memoized function. By default, the - * first argument provided to the memoized function is used as the cache key. - * The `func` is executed with the `this` binding of the memoized function. - * The result cache is exposed as the `cache` property on the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - * - * fibonacci(9) - * // => 34 - * - * var data = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // modifying the result cache - * var get = _.memoize(function(name) { return data[name]; }, _.identity); - * get('pebbles'); - * // => { 'name': 'pebbles', 'age': 1 } - * - * get.cache.pebbles.name = 'penelope'; - * get('pebbles'); - * // => { 'name': 'penelope', 'age': 1 } - */ - function memoize(func, resolver) { - if (!isFunction(func)) { - throw new TypeError; - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; - - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - } - memoized.cache = {}; - return memoized; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those provided to the new function. This - * method is similar to `_.bind` except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('fred'); - * // => 'hi fred' - */ - function partial(func) { - return createWrapper(func, 16, slice(arguments, 1)); - } - - /** - * This method is like `_.partial` except that `partial` arguments are - * appended to those provided to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createWrapper(func, 32, null, slice(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` function - * at most once per every `wait` milliseconds. Provide an options object to - * indicate that `func` should be invoked on the leading and/or trailing edge - * of the `wait` timeout. Subsequent calls to the throttled function will - * return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle executions to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - * - * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? options.leading : leading; - trailing = 'trailing' in options ? options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = wait; - debounceOptions.trailing = trailing; - - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Additional arguments provided to the function are appended - * to those provided to the wrapper function. The wrapper is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

    ' + func(text) + '

    '; - * }); - * - * p('Fred, Wilma, & Pebbles'); - * // => '

    Fred, Wilma, & Pebbles

    ' - */ - function wrap(value, wrapper) { - return createWrapper(wrapper, 16, [value]); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. - * @example - * - * var object = { 'name': 'fred' }; - * var getter = _.constant(object); - * getter() === object; - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ - function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; - - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } - } - return result; - }; - } - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} string The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('Fred, Wilma, & Pebbles'); - * // => 'Fred, Wilma, & Pebbles' - */ - function escape(string) { - return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds function properties of a source object to the destination object. - * If `object` is a function methods will be added to its prototype as well. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Function|Object} [object=lodash] object The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options] The options object. - * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. - * @example - * - * function capitalize(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * - * _.mixin({ 'capitalize': capitalize }); - * _.capitalize('fred'); - * // => 'Fred' - * - * _('fred').capitalize().value(); - * // => 'Fred' - * - * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); - * _('fred').capitalize(); - * // => 'Fred' - */ - function mixin(object, source, options) { - var chain = true, - methodNames = source && functions(source); - - if (!source || (!options && !methodNames.length)) { - if (options == null) { - options = source; - } - ctor = lodashWrapper; - source = object; - object = lodash; - methodNames = functions(source); - } - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - var ctor = object, - isFunc = isFunction(ctor); - - forEach(methodNames, function(methodName) { - var func = object[methodName] = source[methodName]; - if (isFunc) { - ctor.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new ctor(result); - result.__chain__ = chainAll; - } - return result; - }; - } - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - context._ = oldDash; - return this; - } - - /** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ - function noop() { - // no operation performed - } - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var stamp = _.now(); - * _.defer(function() { console.log(_.now() - stamp); }); - * // => logs the number of milliseconds it took for the deferred function to be called - */ - var now = isNative(now = Date.now) && now || function() { - return new Date().getTime(); - }; - - /** - * Converts the given value into an integer of the specified radix. - * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the - * `value` is a hexadecimal, in which case a `radix` of `16` is used. - * - * Note: This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See http://es5.github.io/#E. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} value The value to parse. - * @param {number} [radix] The radix used to interpret the value to parse. - * @returns {number} Returns the new integer value. - * @example - * - * _.parseInt('08'); - * // => 8 - */ - var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` - return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); - }; - - /** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example - * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; - * - * var getName = _.property('name'); - * - * _.map(characters, getName); - * // => ['barney', 'fred'] - * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] - */ - function property(key) { - return function(object) { - return object[key]; - }; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number will be - * returned. If `floating` is truey or either `min` or `max` are floats a - * floating-point number will be returned instead of an integer. - * - * @static - * @memberOf _ - * @category Utilities - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating=false] Specify returning a floating-point number. - * @returns {number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (typeof min == 'boolean' && noMax) { - floating = min; - min = 1; - } - else if (!noMax && typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); - } - return baseRandom(min, max); - } - - /** - * Resolves the value of property `key` on `object`. If `key` is a function - * it will be invoked with the `this` binding of `object` and its result returned, - * else the property value is returned. If `object` is falsey then `undefined` - * is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to resolve. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, key) { - if (object) { - var value = object[key]; - return isFunction(value) ? object[key]() : value; - } - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * For more information on precompiling templates see: - * http://lodash.com/custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} text The template text. - * @param {Object} data The data object used to populate the text. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as local variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [sourceURL] The sourceURL of the template's compiled source. - * @param {string} [variable] The data object variable name. - * @returns {Function|string} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': '').stripTags() -=> 'a linkalert("hello world!")' -``` - -**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) - -Join an array into a human readable sentence. - -```javascript -_.toSentence(['jQuery', 'Mootools', 'Prototype']) -=> 'jQuery, Mootools and Prototype'; - -_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') -=> 'jQuery, Mootools unt Prototype'; -``` - -**toSentenceSerial** _.toSentenceSerial(array, [delimiter, lastDelimiter]) - -The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma). - -```javascript -_.toSentenceSerial(['jQuery', 'Mootools']) -=> 'jQuery and Mootools'; - -_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype']) -=> 'jQuery, Mootools, and Prototype' - -_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt '); -=> 'jQuery, Mootools, unt Prototype'; -``` - -**repeat** _.repeat(string, count, [separator]) - -Repeats a string count times. - -```javascript -_.repeat("foo", 3) -=> 'foofoofoo'; - -_.repeat("foo", 3, "bar") -=> 'foobarfoobarfoo' -``` - -**surround** _.surround(string, wrap) - -Surround a string with another string. - -```javascript -_.surround("foo", "ab") -=> 'abfooab'; -``` - -**quote** _.quote(string, quoteChar) or _.q(string, quoteChar) - -Quotes a string. `quoteChar` defaults to `"`. - -```javascript -_.quote('foo', quoteChar) -=> '"foo"'; -``` -**unquote** _.unquote(string, quoteChar) - -Unquotes a string. `quoteChar` defaults to `"`. - -```javascript -_.unquote('"foo"') -=> 'foo'; -_.unquote("'foo'", "'") -=> 'foo'; -``` - - -**slugify** _.slugify(string) - -Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. - -```javascript -_.slugify("Un éléphant à l'orée du bois") -=> 'un-elephant-a-loree-du-bois'; -``` - -***Caution: this function is charset dependent*** - -**naturalCmp** array.sort(_.naturalCmp) - -Naturally sort strings like humans would do. - -```javascript -['foo20', 'foo5'].sort(_.naturalCmp) -=> [ 'foo5', 'foo20' ] -``` - -**toBoolean** _.toBoolean(string) or _.toBool(string) - -Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive. - -```javascript -_.toBoolean("true") -=> true -_.toBoolean("FALSE") -=> false -_.toBoolean("random") -=> undefined -``` - -It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects. - -```javascript -_.toBoolean("truthy", ["truthy"], ["falsy"]) -=> true -_.toBoolean("true only at start", [/^true/]) -=> true -``` - -## Roadmap ## - -Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. - -#### Problems - -We lose two things for `include` and `reverse` methods from `_.string`: - -* Calls like `_('foobar').include('bar')` aren't available; -* Chaining isn't available too. - -But if you need this functionality you can create aliases for conflict functions which will be convenient for you: - -```javascript -_.mixin({ - includeString: _.str.include, - reverseString: _.str.reverse -}) - -// Now wrapper calls and chaining are available. -_('foobar').chain().reverseString().includeString('rab').value() -``` - -#### Standalone Usage - -If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias -But of course you can just reassign `_` variable with `_.string` - -```javascript -_ = _.string -``` - -## Changelog ## - -### 2.3.3 ### - -* Add `toBoolean` -* Add `unquote` -* Add quote char option to `quote` -* Support dash-separated words in `titleize` - -### 2.3.2 ### - -* Add `naturalCmp` -* Bug fix to `camelize` -* Add ă, ș, ț and ś to `slugify` -* Doc updates -* Add support for [component](http://component.io/) -* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.1...v2.3.2) - -### 2.3.1 ### - -* Bug fixes to `escapeHTML`, `classify`, `substr` -* Faster `count` -* Documentation fixes -* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.0...v2.3.1) - -### 2.3.0 ### - -* Added `numberformat` method -* Added `levenshtein` method (Levenshtein distance calculation) -* Added `swapCase` method -* Changed default behavior of `words` method -* Added `toSentenceSerial` method -* Added `surround` and `quote` methods - -### 2.2.1 ### - -* Same as 2.2.0 (2.2.0rc on npm) to fix some npm drama - -### 2.2.0 ### - -* Capitalize method behavior changed -* Various perfomance tweaks - -### 2.1.1### - -* Fixed words method bug -* Added classify method - -### 2.1.0 ### - -* AMD support -* Added toSentence method -* Added slugify method -* Lots of speed optimizations - -### 2.0.0 ### - -* Added prune, humanize functions -* Added _.string (_.str) namespace for Underscore.string library -* Removed includes function - -For upgrading to this version you need to mix in Underscore.string library to Underscore object: - -```javascript -_.mixin(_.string.exports()); -``` - -and all non-conflict Underscore.string functions will be available through Underscore object. -Also function `includes` has been removed, you should replace this function by `_.str.include` -or create alias `_.includes = _.str.include` and all your code will work fine. - -### 1.1.6 ### - -* Fixed reverse and truncate -* Added isBlank, stripTags, inlude(alias for includes) -* Added uglifier compression - -### 1.1.5 ### - -* Added strRight, strRightBack, strLeft, strLeftBack - -### 1.1.4 ### - -* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust -* Integration with Underscore 1.1.6 - -### 1.1.3 ### - -* Added methods: underscored, camelize, dasherize -* Support newer version of npm - -### 1.1.2 ### - -* Created functions: lines, chars, words functions - -### 1.0.2 ### - -* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) -* Removed 'reverse' function, because this function override underscore.js 'reverse' - -## Contribute ## - -* Fork & pull request. Don't forget about tests. -* If you planning add some feature please create issue before. - -Otherwise changes will be rejected. - -## Contributors list ## -[Can be found here](https://github.com/epeli/underscore.string/graphs/contributors). - - -## Licence ## - -The MIT License - -Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org - -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/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile deleted file mode 100644 index 2cd9eed9..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/Rakefile +++ /dev/null @@ -1,23 +0,0 @@ -# encoding: utf-8 -task default: :test - -desc 'Use UglifyJS to compress Underscore.string' -task :build do - require 'uglifier' - source = File.read('lib/underscore.string.js', :encoding => 'utf-8') - compressed = Uglifier.compile(source, copyright: false) - File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed } - compression_rate = compressed.length.to_f/source.length - puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%" -end - -desc 'Run tests' -task :test do - puts "Running underscore.string test suite." - result1 = system %{phantomjs ./test/run-qunit.js "test/test.html"} - - puts "Running Underscore test suite." - result2 = system %{phantomjs ./test/run-qunit.js "test/test_underscore/index.html"} - - exit(result1 && result2 ? 0 : 1) -end diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json deleted file mode 100644 index ae91b65b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/component.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "underscore.string", - "repo": "epeli/underscore.string", - "description": "String manipulation extensions for Underscore.js javascript library", - "version": "2.3.3", - "keywords": ["underscore", "string"], - "dependencies": {}, - "development": {}, - "main": "lib/underscore.string.js", - "scripts": ["lib/underscore.string.js"] -} diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js deleted file mode 100644 index 4f6b2b93..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/dist/underscore.string.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String); \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js deleted file mode 100644 index 87611173..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/lib/underscore.string.js +++ /dev/null @@ -1,673 +0,0 @@ -// Underscore.string -// (c) 2010 Esa-Matti Suuronen -// Underscore.string is freely distributable under the terms of the MIT license. -// Documentation: https://github.com/epeli/underscore.string -// Some code is borrowed from MooTools and Alexandru Marasteanu. -// Version '2.3.2' - -!function(root, String){ - 'use strict'; - - // Defining helper functions. - - var nativeTrim = String.prototype.trim; - var nativeTrimRight = String.prototype.trimRight; - var nativeTrimLeft = String.prototype.trimLeft; - - var parseNumber = function(source) { return source * 1 || 0; }; - - var strRepeat = function(str, qty){ - if (qty < 1) return ''; - var result = ''; - while (qty > 0) { - if (qty & 1) result += str; - qty >>= 1, str += str; - } - return result; - }; - - var slice = [].slice; - - var defaultToWhiteSpace = function(characters) { - if (characters == null) - return '\\s'; - else if (characters.source) - return characters.source; - else - return '[' + _s.escapeRegExp(characters) + ']'; - }; - - // Helper for toBoolean - function boolMatch(s, matchers) { - var i, matcher, down = s.toLowerCase(); - matchers = [].concat(matchers); - for (i = 0; i < matchers.length; i += 1) { - matcher = matchers[i]; - if (!matcher) continue; - if (matcher.test && matcher.test(s)) return true; - if (matcher.toLowerCase() === down) return true; - } - } - - var escapeChars = { - lt: '<', - gt: '>', - quot: '"', - amp: '&', - apos: "'" - }; - - var reversedEscapeChars = {}; - for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key; - reversedEscapeChars["'"] = '#39'; - - // sprintf() for JavaScript 0.7-beta1 - // http://www.diveintojavascript.com/projects/javascript-sprintf - // - // Copyright (c) Alexandru Marasteanu - // All rights reserved. - - var sprintf = (function() { - function get_type(variable) { - return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); - } - - var str_repeat = strRepeat; - - var str_format = function() { - if (!str_format.cache.hasOwnProperty(arguments[0])) { - str_format.cache[arguments[0]] = str_format.parse(arguments[0]); - } - return str_format.format.call(null, str_format.cache[arguments[0]], arguments); - }; - - str_format.format = function(parse_tree, argv) { - var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; - for (i = 0; i < tree_length; i++) { - node_type = get_type(parse_tree[i]); - if (node_type === 'string') { - output.push(parse_tree[i]); - } - else if (node_type === 'array') { - match = parse_tree[i]; // convenience purposes only - if (match[2]) { // keyword argument - arg = argv[cursor]; - for (k = 0; k < match[2].length; k++) { - if (!arg.hasOwnProperty(match[2][k])) { - throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); - } - arg = arg[match[2][k]]; - } - } else if (match[1]) { // positional argument (explicit) - arg = argv[match[1]]; - } - else { // positional argument (implicit) - arg = argv[cursor++]; - } - - if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { - throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); - } - switch (match[8]) { - case 'b': arg = arg.toString(2); break; - case 'c': arg = String.fromCharCode(arg); break; - case 'd': arg = parseInt(arg, 10); break; - case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; - case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; - case 'o': arg = arg.toString(8); break; - case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; - case 'u': arg = Math.abs(arg); break; - case 'x': arg = arg.toString(16); break; - case 'X': arg = arg.toString(16).toUpperCase(); break; - } - arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); - pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; - pad_length = match[6] - String(arg).length; - pad = match[6] ? str_repeat(pad_character, pad_length) : ''; - output.push(match[5] ? arg + pad : pad + arg); - } - } - return output.join(''); - }; - - str_format.cache = {}; - - str_format.parse = function(fmt) { - var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; - while (_fmt) { - if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { - parse_tree.push(match[0]); - } - else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { - parse_tree.push('%'); - } - else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { - if (match[2]) { - arg_names |= 1; - var field_list = [], replacement_field = match[2], field_match = []; - if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { - if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else { - throw new Error('[_.sprintf] huh?'); - } - } - } - else { - throw new Error('[_.sprintf] huh?'); - } - match[2] = field_list; - } - else { - arg_names |= 2; - } - if (arg_names === 3) { - throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); - } - parse_tree.push(match); - } - else { - throw new Error('[_.sprintf] huh?'); - } - _fmt = _fmt.substring(match[0].length); - } - return parse_tree; - }; - - return str_format; - })(); - - - - // Defining underscore.string - - var _s = { - - VERSION: '2.3.0', - - isBlank: function(str){ - if (str == null) str = ''; - return (/^\s*$/).test(str); - }, - - stripTags: function(str){ - if (str == null) return ''; - return String(str).replace(/<\/?[^>]+>/g, ''); - }, - - capitalize : function(str){ - str = str == null ? '' : String(str); - return str.charAt(0).toUpperCase() + str.slice(1); - }, - - chop: function(str, step){ - if (str == null) return []; - str = String(str); - step = ~~step; - return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; - }, - - clean: function(str){ - return _s.strip(str).replace(/\s+/g, ' '); - }, - - count: function(str, substr){ - if (str == null || substr == null) return 0; - - str = String(str); - substr = String(substr); - - var count = 0, - pos = 0, - length = substr.length; - - while (true) { - pos = str.indexOf(substr, pos); - if (pos === -1) break; - count++; - pos += length; - } - - return count; - }, - - chars: function(str) { - if (str == null) return []; - return String(str).split(''); - }, - - swapCase: function(str) { - if (str == null) return ''; - return String(str).replace(/\S/g, function(c){ - return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); - }); - }, - - escapeHTML: function(str) { - if (str == null) return ''; - return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; }); - }, - - unescapeHTML: function(str) { - if (str == null) return ''; - return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){ - var match; - - if (entityCode in escapeChars) { - return escapeChars[entityCode]; - } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { - return String.fromCharCode(parseInt(match[1], 16)); - } else if (match = entityCode.match(/^#(\d+)$/)) { - return String.fromCharCode(~~match[1]); - } else { - return entity; - } - }); - }, - - escapeRegExp: function(str){ - if (str == null) return ''; - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); - }, - - splice: function(str, i, howmany, substr){ - var arr = _s.chars(str); - arr.splice(~~i, ~~howmany, substr); - return arr.join(''); - }, - - insert: function(str, i, substr){ - return _s.splice(str, i, 0, substr); - }, - - include: function(str, needle){ - if (needle === '') return true; - if (str == null) return false; - return String(str).indexOf(needle) !== -1; - }, - - join: function() { - var args = slice.call(arguments), - separator = args.shift(); - - if (separator == null) separator = ''; - - return args.join(separator); - }, - - lines: function(str) { - if (str == null) return []; - return String(str).split("\n"); - }, - - reverse: function(str){ - return _s.chars(str).reverse().join(''); - }, - - startsWith: function(str, starts){ - if (starts === '') return true; - if (str == null || starts == null) return false; - str = String(str); starts = String(starts); - return str.length >= starts.length && str.slice(0, starts.length) === starts; - }, - - endsWith: function(str, ends){ - if (ends === '') return true; - if (str == null || ends == null) return false; - str = String(str); ends = String(ends); - return str.length >= ends.length && str.slice(str.length - ends.length) === ends; - }, - - succ: function(str){ - if (str == null) return ''; - str = String(str); - return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1); - }, - - titleize: function(str){ - if (str == null) return ''; - str = String(str).toLowerCase(); - return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); }); - }, - - camelize: function(str){ - return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; }); - }, - - underscored: function(str){ - return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); - }, - - dasherize: function(str){ - return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); - }, - - classify: function(str){ - return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, ''); - }, - - humanize: function(str){ - return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); - }, - - trim: function(str, characters){ - if (str == null) return ''; - if (!characters && nativeTrim) return nativeTrim.call(str); - characters = defaultToWhiteSpace(characters); - return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), ''); - }, - - ltrim: function(str, characters){ - if (str == null) return ''; - if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); - characters = defaultToWhiteSpace(characters); - return String(str).replace(new RegExp('^' + characters + '+'), ''); - }, - - rtrim: function(str, characters){ - if (str == null) return ''; - if (!characters && nativeTrimRight) return nativeTrimRight.call(str); - characters = defaultToWhiteSpace(characters); - return String(str).replace(new RegExp(characters + '+$'), ''); - }, - - truncate: function(str, length, truncateStr){ - if (str == null) return ''; - str = String(str); truncateStr = truncateStr || '...'; - length = ~~length; - return str.length > length ? str.slice(0, length) + truncateStr : str; - }, - - /** - * _s.prune: a more elegant version of truncate - * prune extra chars, never leaving a half-chopped word. - * @author github.com/rwz - */ - prune: function(str, length, pruneStr){ - if (str == null) return ''; - - str = String(str); length = ~~length; - pruneStr = pruneStr != null ? String(pruneStr) : '...'; - - if (str.length <= length) return str; - - var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, - template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' - - if (template.slice(template.length-2).match(/\w\w/)) - template = template.replace(/\s*\S+$/, ''); - else - template = _s.rtrim(template.slice(0, template.length-1)); - - return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr; - }, - - words: function(str, delimiter) { - if (_s.isBlank(str)) return []; - return _s.trim(str, delimiter).split(delimiter || /\s+/); - }, - - pad: function(str, length, padStr, type) { - str = str == null ? '' : String(str); - length = ~~length; - - var padlen = 0; - - if (!padStr) - padStr = ' '; - else if (padStr.length > 1) - padStr = padStr.charAt(0); - - switch(type) { - case 'right': - padlen = length - str.length; - return str + strRepeat(padStr, padlen); - case 'both': - padlen = length - str.length; - return strRepeat(padStr, Math.ceil(padlen/2)) + str - + strRepeat(padStr, Math.floor(padlen/2)); - default: // 'left' - padlen = length - str.length; - return strRepeat(padStr, padlen) + str; - } - }, - - lpad: function(str, length, padStr) { - return _s.pad(str, length, padStr); - }, - - rpad: function(str, length, padStr) { - return _s.pad(str, length, padStr, 'right'); - }, - - lrpad: function(str, length, padStr) { - return _s.pad(str, length, padStr, 'both'); - }, - - sprintf: sprintf, - - vsprintf: function(fmt, argv){ - argv.unshift(fmt); - return sprintf.apply(null, argv); - }, - - toNumber: function(str, decimals) { - if (!str) return 0; - str = _s.trim(str); - if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN; - return parseNumber(parseNumber(str).toFixed(~~decimals)); - }, - - numberFormat : function(number, dec, dsep, tsep) { - if (isNaN(number) || number == null) return ''; - - number = number.toFixed(~~dec); - tsep = typeof tsep == 'string' ? tsep : ','; - - var parts = number.split('.'), fnums = parts[0], - decimals = parts[1] ? (dsep || '.') + parts[1] : ''; - - return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; - }, - - strRight: function(str, sep){ - if (str == null) return ''; - str = String(str); sep = sep != null ? String(sep) : sep; - var pos = !sep ? -1 : str.indexOf(sep); - return ~pos ? str.slice(pos+sep.length, str.length) : str; - }, - - strRightBack: function(str, sep){ - if (str == null) return ''; - str = String(str); sep = sep != null ? String(sep) : sep; - var pos = !sep ? -1 : str.lastIndexOf(sep); - return ~pos ? str.slice(pos+sep.length, str.length) : str; - }, - - strLeft: function(str, sep){ - if (str == null) return ''; - str = String(str); sep = sep != null ? String(sep) : sep; - var pos = !sep ? -1 : str.indexOf(sep); - return ~pos ? str.slice(0, pos) : str; - }, - - strLeftBack: function(str, sep){ - if (str == null) return ''; - str += ''; sep = sep != null ? ''+sep : sep; - var pos = str.lastIndexOf(sep); - return ~pos ? str.slice(0, pos) : str; - }, - - toSentence: function(array, separator, lastSeparator, serial) { - separator = separator || ', '; - lastSeparator = lastSeparator || ' and '; - var a = array.slice(), lastMember = a.pop(); - - if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator; - - return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; - }, - - toSentenceSerial: function() { - var args = slice.call(arguments); - args[3] = true; - return _s.toSentence.apply(_s, args); - }, - - slugify: function(str) { - if (str == null) return ''; - - var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź", - to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz", - regex = new RegExp(defaultToWhiteSpace(from), 'g'); - - str = String(str).toLowerCase().replace(regex, function(c){ - var index = from.indexOf(c); - return to.charAt(index) || '-'; - }); - - return _s.dasherize(str.replace(/[^\w\s-]/g, '')); - }, - - surround: function(str, wrapper) { - return [wrapper, str, wrapper].join(''); - }, - - quote: function(str, quoteChar) { - return _s.surround(str, quoteChar || '"'); - }, - - unquote: function(str, quoteChar) { - quoteChar = quoteChar || '"'; - if (str[0] === quoteChar && str[str.length-1] === quoteChar) - return str.slice(1,str.length-1); - else return str; - }, - - exports: function() { - var result = {}; - - for (var prop in this) { - if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue; - result[prop] = this[prop]; - } - - return result; - }, - - repeat: function(str, qty, separator){ - if (str == null) return ''; - - qty = ~~qty; - - // using faster implementation if separator is not needed; - if (separator == null) return strRepeat(String(str), qty); - - // this one is about 300x slower in Google Chrome - for (var repeat = []; qty > 0; repeat[--qty] = str) {} - return repeat.join(separator); - }, - - naturalCmp: function(str1, str2){ - if (str1 == str2) return 0; - if (!str1) return -1; - if (!str2) return 1; - - var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g, - tokens1 = String(str1).toLowerCase().match(cmpRegex), - tokens2 = String(str2).toLowerCase().match(cmpRegex), - count = Math.min(tokens1.length, tokens2.length); - - for(var i = 0; i < count; i++) { - var a = tokens1[i], b = tokens2[i]; - - if (a !== b){ - var num1 = parseInt(a, 10); - if (!isNaN(num1)){ - var num2 = parseInt(b, 10); - if (!isNaN(num2) && num1 - num2) - return num1 - num2; - } - return a < b ? -1 : 1; - } - } - - if (tokens1.length === tokens2.length) - return tokens1.length - tokens2.length; - - return str1 < str2 ? -1 : 1; - }, - - levenshtein: function(str1, str2) { - if (str1 == null && str2 == null) return 0; - if (str1 == null) return String(str2).length; - if (str2 == null) return String(str1).length; - - str1 = String(str1); str2 = String(str2); - - var current = [], prev, value; - - for (var i = 0; i <= str2.length; i++) - for (var j = 0; j <= str1.length; j++) { - if (i && j) - if (str1.charAt(j - 1) === str2.charAt(i - 1)) - value = prev; - else - value = Math.min(current[j], current[j - 1], prev) + 1; - else - value = i + j; - - prev = current[j]; - current[j] = value; - } - - return current.pop(); - }, - - toBoolean: function(str, trueValues, falseValues) { - if (typeof str === "number") str = "" + str; - if (typeof str !== "string") return !!str; - str = _s.trim(str); - if (boolMatch(str, trueValues || ["true", "1"])) return true; - if (boolMatch(str, falseValues || ["false", "0"])) return false; - } - }; - - // Aliases - - _s.strip = _s.trim; - _s.lstrip = _s.ltrim; - _s.rstrip = _s.rtrim; - _s.center = _s.lrpad; - _s.rjust = _s.lpad; - _s.ljust = _s.rpad; - _s.contains = _s.include; - _s.q = _s.quote; - _s.toBool = _s.toBoolean; - - // Exporting - - // CommonJS module is defined - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) - module.exports = _s; - - exports._s = _s; - } - - // Register as a named module with AMD. - if (typeof define === 'function' && define.amd) - define('underscore.string', [], function(){ return _s; }); - - - // Integrate with Underscore.js if defined - // or create our own underscore object. - root._ = root._ || {}; - root._.string = root._.str = _s; -}(this, String); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/libpeerconnection.log deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json deleted file mode 100644 index 1d0ca134..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/package.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "name": "underscore.string", - "version": "2.3.3", - "description": "String manipulation extensions for Underscore.js javascript library.", - "homepage": "http://epeli.github.com/underscore.string/", - "contributors": [ - { - "name": "Esa-Matti Suuronen", - "email": "esa-matti@suuronen.org", - "url": "http://esa-matti.suuronen.org/" - }, - { - "name": "Edward Tsech", - "email": "edtsech@gmail.com" - }, - { - "name": "Pavel Pravosud", - "email": "pavel@pravosud.com", - "url": "" - }, - { - "name": "Sasha Koss", - "email": "kossnocorp@gmail.com", - "url": "http://koss.nocorp.me/" - }, - { - "name": "Vladimir Dronnikov", - "email": "dronnikov@gmail.com" - }, - { - "name": "Pete Kruckenberg", - "email": "https://github.com/kruckenb", - "url": "" - }, - { - "name": "Paul Chavard", - "email": "paul@chavard.net", - "url": "" - }, - { - "name": "Ed Finkler", - "email": "coj@funkatron.com", - "url": "" - } - ], - "keywords": [ - "underscore", - "string" - ], - "main": "./lib/underscore.string", - "directories": { - "lib": "./lib" - }, - "engines": { - "node": "*" - }, - "repository": { - "type": "git", - "url": "https://github.com/epeli/underscore.string.git" - }, - "bugs": { - "url": "https://github.com/epeli/underscore.string/issues" - }, - "licenses": [ - { - "type": "MIT" - } - ], - "_id": "underscore.string@2.3.3", - "dist": { - "shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", - "tarball": "http://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" - }, - "_from": "underscore.string@~2.3.3", - "_npmVersion": "1.2.32", - "_npmUser": { - "name": "epeli", - "email": "esa-matti@suuronen.org" - }, - "maintainers": [ - { - "name": "edtsech", - "email": "edtsech@gmail.com" - }, - { - "name": "rwz", - "email": "rwz@duckroll.ru" - }, - { - "name": "epeli", - "email": "esa-matti@suuronen.org" - } - ], - "_shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", - "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "readme": "ERROR: No README data found!", - "scripts": {} -} diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js deleted file mode 100644 index 44a21670..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/run-qunit.js +++ /dev/null @@ -1,45 +0,0 @@ -function waitFor(test, complete, timeout) { - var result, start = new Date().getTime() - setInterval(function interval() { - if ((new Date().getTime() - start < timeout) && !result) { - result = test() - } else { - if (!result) { - phantom.exit(1) - } else { - complete() - clearInterval(interval) - } - } - }, 100) -} - - -var fs = require('fs'), page = require('webpage').create(); -var url = 'file://localhost' + fs.workingDirectory + '/' + phantom.args[0]; - -page.onConsoleMessage = function(msg) { - console.log(msg) -} - -page.open(url, function(status) { - waitFor(function() { - return page.evaluate(function(){ - var el = document.getElementById('qunit-testresult') - return el && el.innerText.match('completed') - }) - }, function() { - var failures = page.evaluate(function() { - var el = document.getElementById('qunit-testresult'), - fails = document.getElementsByClassName('fail') - - for (var i = 0; i < fails.length; i++) - console.log(fails[i].innerText) - - console.log(el.innerText) - - return parseInt(el.getElementsByClassName('failed')[0].innerHTML) - }) - phantom.exit(failures > 0 ? 1 : 0) - }, 10000) -}) \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js deleted file mode 100644 index 9ceeea76..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/speed.js +++ /dev/null @@ -1,148 +0,0 @@ -(function() { - - JSLitmus.test('levenshtein', function() { - return [ - _.levenshtein('pineapple', 'potato'), - _.levenshtein('seven', 'eight'), - _.levenshtein('the very same string', 'the very same string'), - _.levenshtein('very very very long string', 'something completely different') - ]; - }); - - - JSLitmus.test('trimNoNative', function() { - return _.trim(" foobar ", " "); - }); - - JSLitmus.test('trim', function() { - return _.trim(" foobar "); - }); - - JSLitmus.test('trim object-oriented', function() { - return _(" foobar ").trim(); - }); - - JSLitmus.test('trim jQuery', function() { - return jQuery.trim(" foobar "); - }); - - JSLitmus.test('ltrimp', function() { - return _.ltrim(" foobar ", " "); - }); - - JSLitmus.test('rtrimp', function() { - return _.rtrim(" foobar ", " "); - }); - - JSLitmus.test('startsWith', function() { - return _.startsWith("foobar", "foo"); - }); - - JSLitmus.test('endsWith', function() { - return _.endsWith("foobar", "xx"); - }); - - JSLitmus.test('chop', function(){ - return _('whitespace').chop(2); - }); - - JSLitmus.test('count', function(){ - return _('Hello worls').count('l'); - }); - - JSLitmus.test('insert', function() { - return _('Hello ').insert(6, 'world'); - }); - - JSLitmus.test('splice', function() { - return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); - }); - - JSLitmus.test('succ', function(){ - var let = 'a', alphabet = []; - - for (var i=0; i < 26; i++) { - alphabet.push(let); - let = _(let).succ(); - } - - return alphabet; - }); - - JSLitmus.test('titleize', function(){ - return _('the titleize string method').titleize(); - }); - - JSLitmus.test('truncate', function(){ - return _('Hello world').truncate(5); - }); - - JSLitmus.test('prune', function(){ - return _('Hello world').prune(5); - }); - - JSLitmus.test('isBlank', function(){ - return _('').isBlank(); - }); - - JSLitmus.test('escapeHTML', function(){ - _('
    Blah blah blah
    ').escapeHTML(); - }); - - JSLitmus.test('unescapeHTML', function(){ - _('<div>Blah blah blah</div>').unescapeHTML(); - }); - - JSLitmus.test('reverse', function(){ - _('Hello World').reverse(); - }); - - JSLitmus.test('pad default', function(){ - _('foo').pad(12); - }); - - JSLitmus.test('pad hash left', function(){ - _('foo').pad(12, '#'); - }); - - JSLitmus.test('pad hash right', function(){ - _('foo').pad(12, '#', 'right'); - }); - - JSLitmus.test('pad hash both', function(){ - _('foo').pad(12, '#', 'both'); - }); - - JSLitmus.test('pad hash both longPad', function(){ - _('foo').pad(12, 'f00f00f00', 'both'); - }); - - JSLitmus.test('toNumber', function(){ - _('10.232323').toNumber(2); - }); - - JSLitmus.test('strRight', function(){ - _('aaa_bbb_ccc').strRight('_'); - }); - - JSLitmus.test('strRightBack', function(){ - _('aaa_bbb_ccc').strRightBack('_'); - }); - - JSLitmus.test('strLeft', function(){ - _('aaa_bbb_ccc').strLeft('_'); - }); - - JSLitmus.test('strLeftBack', function(){ - _('aaa_bbb_ccc').strLeftBack('_'); - }); - - JSLitmus.test('join', function(){ - _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut'); - }); - - JSLitmus.test('slugify', function(){ - _("Un éléphant à l'orée du bois").slugify(); - }); - -})(); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js deleted file mode 100644 index 77364f20..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/strings.js +++ /dev/null @@ -1,685 +0,0 @@ -$(document).ready(function() { - - // Include Underscore.string methods to Underscore namespace - _.mixin(_.str.exports()); - - module('String extensions'); - - test('Strings: naturalSort', function() { - var arr = ['foo2', 'foo1', 'foo10', 'foo30', 'foo100', 'foo10bar'], - sorted = ['foo1', 'foo2', 'foo10', 'foo10bar', 'foo30', 'foo100']; - deepEqual(arr.sort(_.naturalCmp), sorted); - }); - - test('Strings: trim', function() { - equal(_.trim(123), '123', 'Non string'); - equal(_(' foo').trim(), 'foo'); - equal(_('foo ').trim(), 'foo'); - equal(_(' foo ').trim(), 'foo'); - equal(_(' foo ').trim(), 'foo'); - equal(_(' foo ').trim(' '), 'foo', 'Manually set whitespace'); - equal(_('\t foo \t ').trim(/\s/), 'foo', 'Manually set RegExp /\\s+/'); - - equal(_('ffoo').trim('f'), 'oo'); - equal(_('ooff').trim('f'), 'oo'); - equal(_('ffooff').trim('f'), 'oo'); - - - equal(_('_-foobar-_').trim('_-'), 'foobar'); - - equal(_('http://foo/').trim('/'), 'http://foo'); - equal(_('c:\\').trim('\\'), 'c:'); - - equal(_(123).trim(), '123'); - equal(_(123).trim(3), '12'); - equal(_('').trim(), '', 'Trim empty string should return empty string'); - equal(_(null).trim(), '', 'Trim null should return empty string'); - equal(_(undefined).trim(), '', 'Trim undefined should return empty string'); - }); - - test('String: levenshtein', function() { - equal(_.levenshtein('Godfather', 'Godfather'), 0); - equal(_.levenshtein('Godfather', 'Godfathe'), 1); - equal(_.levenshtein('Godfather', 'odfather'), 1); - equal(_.levenshtein('Godfather', 'Gdfthr'), 3); - equal(_.levenshtein('seven', 'eight'), 5); - equal(_.levenshtein('123', 123), 0); - equal(_.levenshtein(321, '321'), 0); - equal(_.levenshtein('lol', null), 3); - equal(_.levenshtein('lol'), 3); - equal(_.levenshtein(null, 'lol'), 3); - equal(_.levenshtein(undefined, 'lol'), 3); - equal(_.levenshtein(), 0); - }); - - test('Strings: ltrim', function() { - equal(_(' foo').ltrim(), 'foo'); - equal(_(' foo').ltrim(), 'foo'); - equal(_('foo ').ltrim(), 'foo '); - equal(_(' foo ').ltrim(), 'foo '); - equal(_('').ltrim(), '', 'ltrim empty string should return empty string'); - equal(_(null).ltrim(), '', 'ltrim null should return empty string'); - equal(_(undefined).ltrim(), '', 'ltrim undefined should return empty string'); - - equal(_('ffoo').ltrim('f'), 'oo'); - equal(_('ooff').ltrim('f'), 'ooff'); - equal(_('ffooff').ltrim('f'), 'ooff'); - - equal(_('_-foobar-_').ltrim('_-'), 'foobar-_'); - - equal(_(123).ltrim(1), '23'); - }); - - test('Strings: rtrim', function() { - equal(_('http://foo/').rtrim('/'), 'http://foo', 'clean trailing slash'); - equal(_(' foo').rtrim(), ' foo'); - equal(_('foo ').rtrim(), 'foo'); - equal(_('foo ').rtrim(), 'foo'); - equal(_('foo bar ').rtrim(), 'foo bar'); - equal(_(' foo ').rtrim(), ' foo'); - - equal(_('ffoo').rtrim('f'), 'ffoo'); - equal(_('ooff').rtrim('f'), 'oo'); - equal(_('ffooff').rtrim('f'), 'ffoo'); - - equal(_('_-foobar-_').rtrim('_-'), '_-foobar'); - - equal(_(123).rtrim(3), '12'); - equal(_('').rtrim(), '', 'rtrim empty string should return empty string'); - equal(_(null).rtrim(), '', 'rtrim null should return empty string'); - }); - - test('Strings: capitalize', function() { - equal(_('fabio').capitalize(), 'Fabio', 'First letter is upper case'); - equal(_.capitalize('fabio'), 'Fabio', 'First letter is upper case'); - equal(_.capitalize('FOO'), 'FOO', 'Other letters unchanged'); - equal(_(123).capitalize(), '123', 'Non string'); - equal(_.capitalize(''), '', 'Capitalizing empty string returns empty string'); - equal(_.capitalize(null), '', 'Capitalizing null returns empty string'); - equal(_.capitalize(undefined), '', 'Capitalizing undefined returns empty string'); - }); - - test('Strings: join', function() { - equal(_.join('', 'foo', 'bar'), 'foobar', 'basic join'); - equal(_.join('', 1, 'foo', 2), '1foo2', 'join numbers and strings'); - equal(_.join(' ','foo', 'bar'), 'foo bar', 'join with spaces'); - equal(_.join('1', '2', '2'), '212', 'join number strings'); - equal(_.join(1, 2, 2), '212', 'join numbers'); - equal(_.join('','foo', null), 'foo', 'join null with string returns string'); - equal(_.join(null,'foo', 'bar'), 'foobar', 'join strings with null returns string'); - equal(_(' ').join('foo', 'bar'), 'foo bar', 'join object oriented'); - }); - - test('Strings: reverse', function() { - equal(_.str.reverse('foo'), 'oof' ); - equal(_.str.reverse('foobar'), 'raboof' ); - equal(_.str.reverse('foo bar'), 'rab oof' ); - equal(_.str.reverse('saippuakauppias'), 'saippuakauppias' ); - equal(_.str.reverse(123), '321', 'Non string'); - equal(_.str.reverse(123.45), '54.321', 'Non string'); - equal(_.str.reverse(''), '', 'reversing empty string returns empty string' ); - equal(_.str.reverse(null), '', 'reversing null returns empty string' ); - equal(_.str.reverse(undefined), '', 'reversing undefined returns empty string' ); - }); - - test('Strings: clean', function() { - equal(_(' foo bar ').clean(), 'foo bar'); - equal(_(123).clean(), '123'); - equal(_('').clean(), '', 'claning empty string returns empty string'); - equal(_(null).clean(), '', 'claning null returns empty string'); - equal(_(undefined).clean(), '', 'claning undefined returns empty string'); - }); - - test('Strings: sprintf', function() { - // Should be very tested function already. Thanks to - // http://www.diveintojavascript.com/projects/sprintf-for-javascript - equal(_.sprintf('Hello %s', 'me'), 'Hello me', 'basic'); - equal(_('Hello %s').sprintf('me'), 'Hello me', 'object'); - equal(_('hello %s').chain().sprintf('me').capitalize().value(), 'Hello me', 'Chaining works'); - equal(_.sprintf('%.1f', 1.22222), '1.2', 'round'); - equal(_.sprintf('%.1f', 1.17), '1.2', 'round 2'); - equal(_.sprintf('%(id)d - %(name)s', {id: 824, name: 'Hello World'}), '824 - Hello World', 'Named replacements work'); - equal(_.sprintf('%(args[0].id)d - %(args[1].name)s', {args: [{id: 824}, {name: 'Hello World'}]}), '824 - Hello World', 'Named replacements with arrays work'); - }); - - - test('Strings: vsprintf', function() { - equal(_.vsprintf('Hello %s', ['me']), 'Hello me', 'basic'); - equal(_('Hello %s').vsprintf(['me']), 'Hello me', 'object'); - equal(_('hello %s').chain().vsprintf(['me']).capitalize().value(), 'Hello me', 'Chaining works'); - equal(_.vsprintf('%.1f', [1.22222]), '1.2', 'round'); - equal(_.vsprintf('%.1f', [1.17]), '1.2', 'round 2'); - equal(_.vsprintf('%(id)d - %(name)s', [{id: 824, name: 'Hello World'}]), '824 - Hello World', 'Named replacement works'); - equal(_.vsprintf('%(args[0].id)d - %(args[1].name)s', [{args: [{id: 824}, {name: 'Hello World'}]}]), '824 - Hello World', 'Named replacement with arrays works'); - }); - - test('Strings: startsWith', function() { - ok(_('foobar').startsWith('foo'), 'foobar starts with foo'); - ok(!_('oobar').startsWith('foo'), 'oobar does not start with foo'); - ok(_(12345).startsWith(123), '12345 starts with 123'); - ok(!_(2345).startsWith(123), '2345 does not start with 123'); - ok(_('').startsWith(''), 'empty string starts with empty string'); - ok(_(null).startsWith(''), 'null starts with empty string'); - ok(!_(null).startsWith('foo'), 'null starts with foo'); - }); - - test('Strings: endsWith', function() { - ok(_('foobar').endsWith('bar'), 'foobar ends with bar'); - ok(_.endsWith('foobar', 'bar'), 'foobar ends with bar'); - ok(_.endsWith('00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4', 'mp4'), 'endsWith .mp4'); - ok(!_('fooba').endsWith('bar'), 'fooba does not end with bar'); - ok(_.endsWith(12345, 45), '12345 ends with 45'); - ok(!_.endsWith(12345, 6), '12345 does not end with 6'); - ok(_('').endsWith(''), 'empty string ends with empty string'); - ok(_(null).endsWith(''), 'null ends with empty string'); - ok(!_(null).endsWith('foo'), 'null ends with foo'); - }); - - test('Strings: include', function() { - ok(_.str.include('foobar', 'bar'), 'foobar includes bar'); - ok(!_.str.include('foobar', 'buzz'), 'foobar does not includes buzz'); - ok(_.str.include(12345, 34), '12345 includes 34'); - ok(!_.str.contains(12345, 6), '12345 does not includes 6'); - ok(!_.str.include('', 34), 'empty string includes 34'); - ok(!_.str.include(null, 34), 'null includes 34'); - ok(_.str.include(null, ''), 'null includes empty string'); - }); - - test('String: chop', function(){ - ok(_('whitespace').chop(2).length === 5, 'output [wh, it, es, pa, ce]'); - ok(_('whitespace').chop(3).length === 4, 'output [whi, tes, pac, e]'); - ok(_('whitespace').chop()[0].length === 10, 'output [whitespace]'); - ok(_(12345).chop(1).length === 5, 'output [1, 2, 3, 4, 5]'); - }); - - test('String: clean', function(){ - equal(_.clean(' foo bar '), 'foo bar'); - equal(_.clean(''), ''); - equal(_.clean(null), ''); - equal(_.clean(1), '1'); - }); - - test('String: count', function(){ - equal(_('Hello world').count('l'), 3); - equal(_('Hello world').count('Hello'), 1); - equal(_('Hello world').count('foo'), 0); - equal(_('x.xx....x.x').count('x'), 5); - equal(_('').count('x'), 0); - equal(_(null).count('x'), 0); - equal(_(undefined).count('x'), 0); - equal(_(12345).count(1), 1); - equal(_(11345).count(1), 2); - }); - - test('String: insert', function(){ - equal(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); - equal(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy'); - equal(_('').insert(100, 'Jessy'), 'Jessy'); - equal(_(null).insert(100, 'Jessy'), 'Jessy'); - equal(_(undefined).insert(100, 'Jessy'), 'Jessy'); - equal(_(12345).insert(6, 'Jessy'), '12345Jessy'); - }); - - test('String: splice', function(){ - equal(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), - 'https://edtsech@bitbucket.org/epeli/underscore.strings'); - equal(_.splice(12345, 1, 2, 321), '132145', 'Non strings'); - }); - - test('String: succ', function(){ - equal(_('a').succ(), 'b'); - equal(_('A').succ(), 'B'); - equal(_('+').succ(), ','); - equal(_(1).succ(), '2'); - }); - - test('String: titleize', function(){ - equal(_('the titleize string method').titleize(), 'The Titleize String Method'); - equal(_('the titleize string method').titleize(), 'The Titleize String Method'); - equal(_('').titleize(), '', 'Titleize empty string returns empty string'); - equal(_(null).titleize(), '', 'Titleize null returns empty string'); - equal(_(undefined).titleize(), '', 'Titleize undefined returns empty string'); - equal(_('let\'s have some fun').titleize(), 'Let\'s Have Some Fun'); - equal(_('a-dash-separated-string').titleize(), 'A-Dash-Separated-String'); - equal(_('A-DASH-SEPARATED-STRING').titleize(), 'A-Dash-Separated-String'); - equal(_(123).titleize(), '123'); - }); - - test('String: camelize', function(){ - equal(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); - equal(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); - equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); - equal(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); - equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); - equal(_('').camelize(), '', 'Camelize empty string returns empty string'); - equal(_(null).camelize(), '', 'Camelize null returns empty string'); - equal(_(undefined).camelize(), '', 'Camelize undefined returns empty string'); - equal(_(123).camelize(), '123'); - }); - - test('String: underscored', function(){ - equal(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); - equal(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); - equal(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); - equal(_(' the underscored string method').underscored(), 'the_underscored_string_method'); - equal(_('').underscored(), ''); - equal(_(null).underscored(), ''); - equal(_(undefined).underscored(), ''); - equal(_(123).underscored(), '123'); - }); - - test('String: dasherize', function(){ - equal(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); - equal(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); - equal(_('thisIsATest').dasherize(), 'this-is-a-test'); - equal(_('this Is A Test').dasherize(), 'this-is-a-test'); - equal(_('thisIsATest123').dasherize(), 'this-is-a-test123'); - equal(_('123thisIsATest').dasherize(), '123this-is-a-test'); - equal(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); - equal(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); - equal(_('téléphone').dasherize(), 'téléphone'); - equal(_('foo$bar').dasherize(), 'foo$bar'); - equal(_('').dasherize(), ''); - equal(_(null).dasherize(), ''); - equal(_(undefined).dasherize(), ''); - equal(_(123).dasherize(), '123'); - }); - - test('String: camelize', function(){ - equal(_.camelize('-moz-transform'), 'MozTransform'); - equal(_.camelize('webkit-transform'), 'webkitTransform'); - equal(_.camelize('under_scored'), 'underScored'); - equal(_.camelize(' with spaces'), 'withSpaces'); - equal(_('').camelize(), ''); - equal(_(null).camelize(), ''); - equal(_(undefined).camelize(), ''); - equal(_("_som eWeird---name-").camelize(), 'SomEWeirdName'); - }); - - test('String: join', function(){ - equal(_.join(1, 2, 3, 4), '21314'); - equal(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz'); - equal(_.join('',2,3,null), '23'); - equal(_.join(null,2,3), '23'); - }); - - test('String: classify', function(){ - equal(_.classify(1), '1'); - equal(_('some_class_name').classify(), 'SomeClassName'); - equal(_('my wonderfull class_name').classify(), 'MyWonderfullClassName'); - equal(_('my wonderfull.class.name').classify(), 'MyWonderfullClassName'); - }); - - test('String: humanize', function(){ - equal(_('the_humanize_string_method').humanize(), 'The humanize string method'); - equal(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method'); - equal(_('the humanize string method').humanize(), 'The humanize string method'); - equal(_('the humanize_id string method_id').humanize(), 'The humanize id string method'); - equal(_('the humanize string method ').humanize(), 'The humanize string method'); - equal(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim'); - equal(_(123).humanize(), '123'); - equal(_('').humanize(), ''); - equal(_(null).humanize(), ''); - equal(_(undefined).humanize(), ''); - }); - - test('String: truncate', function(){ - equal(_('Hello world').truncate(6, 'read more'), 'Hello read more'); - equal(_('Hello world').truncate(5), 'Hello...'); - equal(_('Hello').truncate(10), 'Hello'); - equal(_('').truncate(10), ''); - equal(_(null).truncate(10), ''); - equal(_(undefined).truncate(10), ''); - equal(_(1234567890).truncate(5), '12345...'); - }); - - test('String: prune', function(){ - equal(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more'); - equal(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world'); - equal(_('Hello, world').prune(5), 'Hello...'); - equal(_('Hello, world').prune(8), 'Hello...'); - equal(_('Hello, cruel world').prune(15), 'Hello, cruel...'); - equal(_('Hello world').prune(22), 'Hello world'); - equal(_('Привет, жеÑтокий мир').prune(6, ' read more'), 'Привет read more'); - equal(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир'); - equal(_('Привет, мир').prune(6), 'Привет...'); - equal(_('Привет, мир').prune(8), 'Привет...'); - equal(_('Привет, жеÑтокий мир').prune(16), 'Привет, жеÑтокий...'); - equal(_('Привет, мир').prune(22), 'Привет, мир'); - equal(_('alksjd!!!!!!....').prune(100, ''), 'alksjd!!!!!!....'); - equal(_(123).prune(10), '123'); - equal(_(123).prune(1, 321), '321'); - equal(_('').prune(5), ''); - equal(_(null).prune(5), ''); - equal(_(undefined).prune(5), ''); - }); - - test('String: isBlank', function(){ - ok(_('').isBlank()); - ok(_(' ').isBlank()); - ok(_('\n').isBlank()); - ok(!_('a').isBlank()); - ok(!_('0').isBlank()); - ok(!_(0).isBlank()); - ok(_('').isBlank()); - ok(_(null).isBlank()); - ok(_(undefined).isBlank()); - }); - - test('String: escapeRegExp', function(){ - equal(_.escapeRegExp(/hello(?=\sworld)/.source), 'hello\\(\\?\\=\\\\sworld\\)', 'with lookahead'); - equal(_.escapeRegExp(/hello(?!\shell)/.source), 'hello\\(\\?\\!\\\\shell\\)', 'with negative lookahead'); - }); - - test('String: escapeHTML', function(){ - equal(_('
    Blah & "blah" & \'blah\'
    ').escapeHTML(), - '<div>Blah & "blah" & 'blah'</div>'); - equal(_('<').escapeHTML(), '&lt;'); - equal(_(5).escapeHTML(), '5'); - equal(_('').escapeHTML(), ''); - equal(_(null).escapeHTML(), ''); - equal(_(undefined).escapeHTML(), ''); - }); - - test('String: unescapeHTML', function(){ - equal(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(), - '
    Blah & "blah" & \'blah\'
    '); - equal(_('&lt;').unescapeHTML(), '<'); - equal(_(''').unescapeHTML(), '\''); - equal(_(''').unescapeHTML(), '\''); - equal(_(''').unescapeHTML(), '\''); - equal(_('J').unescapeHTML(), 'J'); - equal(_('J').unescapeHTML(), 'J'); - equal(_('J').unescapeHTML(), 'J'); - equal(_('&_#39;').unescapeHTML(), '&_#39;'); - equal(_(''_;').unescapeHTML(), ''_;'); - equal(_('&#38;').unescapeHTML(), '&'); - equal(_('&amp;').unescapeHTML(), '&'); - equal(_('').unescapeHTML(), ''); - equal(_(null).unescapeHTML(), ''); - equal(_(undefined).unescapeHTML(), ''); - equal(_(5).unescapeHTML(), '5'); - // equal(_(undefined).unescapeHTML(), ''); - }); - - test('String: words', function() { - deepEqual(_('I love you!').words(), ['I', 'love', 'you!']); - deepEqual(_(' I love you! ').words(), ['I', 'love', 'you!']); - deepEqual(_('I_love_you!').words('_'), ['I', 'love', 'you!']); - deepEqual(_('I-love-you!').words(/-/), ['I', 'love', 'you!']); - deepEqual(_(123).words(), ['123'], '123 number has one word "123".'); - deepEqual(_(0).words(), ['0'], 'Zero number has one word "0".'); - deepEqual(_('').words(), [], 'Empty strings has no words.'); - deepEqual(_(' ').words(), [], 'Blank strings has no words.'); - deepEqual(_(null).words(), [], 'null has no words.'); - deepEqual(_(undefined).words(), [], 'undefined has no words.'); - }); - - test('String: chars', function() { - equal(_('Hello').chars().length, 5); - equal(_(123).chars().length, 3); - equal(_('').chars().length, 0); - equal(_(null).chars().length, 0); - equal(_(undefined).chars().length, 0); - }); - - test('String: swapCase', function(){ - equal(_('AaBbCcDdEe').swapCase(), 'aAbBcCdDeE'); - equal(_('Hello World').swapCase(), 'hELLO wORLD'); - equal(_('').swapCase(), ''); - equal(_(null).swapCase(), ''); - equal(_(undefined).swapCase(), ''); - }); - - test('String: lines', function() { - equal(_('Hello\nWorld').lines().length, 2); - equal(_('Hello World').lines().length, 1); - equal(_(123).lines().length, 1); - equal(_('').lines().length, 1); - equal(_(null).lines().length, 0); - equal(_(undefined).lines().length, 0); - }); - - test('String: pad', function() { - equal(_('1').pad(8), ' 1'); - equal(_(1).pad(8), ' 1'); - equal(_('1').pad(8, '0'), '00000001'); - equal(_('1').pad(8, '0', 'left'), '00000001'); - equal(_('1').pad(8, '0', 'right'), '10000000'); - equal(_('1').pad(8, '0', 'both'), '00001000'); - equal(_('foo').pad(8, '0', 'both'), '000foo00'); - equal(_('foo').pad(7, '0', 'both'), '00foo00'); - equal(_('foo').pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); - equal(_('').pad(2), ' '); - equal(_(null).pad(2), ' '); - equal(_(undefined).pad(2), ' '); - }); - - test('String: lpad', function() { - equal(_('1').lpad(8), ' 1'); - equal(_(1).lpad(8), ' 1'); - equal(_('1').lpad(8, '0'), '00000001'); - equal(_('1').lpad(8, '0', 'left'), '00000001'); - equal(_('').lpad(2), ' '); - equal(_(null).lpad(2), ' '); - equal(_(undefined).lpad(2), ' '); - }); - - test('String: rpad', function() { - equal(_('1').rpad(8), '1 '); - equal(_(1).lpad(8), ' 1'); - equal(_('1').rpad(8, '0'), '10000000'); - equal(_('foo').rpad(8, '0'), 'foo00000'); - equal(_('foo').rpad(7, '0'), 'foo0000'); - equal(_('').rpad(2), ' '); - equal(_(null).rpad(2), ' '); - equal(_(undefined).rpad(2), ' '); - }); - - test('String: lrpad', function() { - equal(_('1').lrpad(8), ' 1 '); - equal(_(1).lrpad(8), ' 1 '); - equal(_('1').lrpad(8, '0'), '00001000'); - equal(_('foo').lrpad(8, '0'), '000foo00'); - equal(_('foo').lrpad(7, '0'), '00foo00'); - equal(_('foo').lrpad(7, '!@$%dofjrofj'), '!!foo!!'); - equal(_('').lrpad(2), ' '); - equal(_(null).lrpad(2), ' '); - equal(_(undefined).lrpad(2), ' '); - }); - - test('String: toNumber', function() { - deepEqual(_('not a number').toNumber(), NaN); - equal(_(0).toNumber(), 0); - equal(_('0').toNumber(), 0); - equal(_('0.0').toNumber(), 0); - equal(_('0.1').toNumber(), 0); - equal(_('0.1').toNumber(1), 0.1); - equal(_(' 0.1 ').toNumber(1), 0.1); - equal(_('0000').toNumber(), 0); - equal(_('2.345').toNumber(), 2); - equal(_('2.345').toNumber(NaN), 2); - equal(_('2.345').toNumber(2), 2.35); - equal(_('2.344').toNumber(2), 2.34); - equal(_('2').toNumber(2), 2.00); - equal(_(2).toNumber(2), 2.00); - equal(_(-2).toNumber(), -2); - equal(_('-2').toNumber(), -2); - equal(_('').toNumber(), 0); - equal(_(null).toNumber(), 0); - equal(_(undefined).toNumber(), 0); - }); - - test('String: numberFormat', function() { - equal(_.numberFormat(9000), '9,000'); - equal(_.numberFormat(9000, 0), '9,000'); - equal(_.numberFormat(9000, 0, '', ''), '9000'); - equal(_.numberFormat(90000, 2), '90,000.00'); - equal(_.numberFormat(1000.754), '1,001'); - equal(_.numberFormat(1000.754, 2), '1,000.75'); - equal(_.numberFormat(1000.754, 0, ',', '.'), '1.001'); - equal(_.numberFormat(1000.754, 2, ',', '.'), '1.000,75'); - equal(_.numberFormat(1000000.754, 2, ',', '.'), '1.000.000,75'); - equal(_.numberFormat(1000000000), '1,000,000,000'); - equal(_.numberFormat(100000000), '100,000,000'); - equal(_.numberFormat('not number'), ''); - equal(_.numberFormat(), ''); - equal(_.numberFormat(null, '.', ','), ''); - equal(_.numberFormat(undefined, '.', ','), ''); - equal(_.numberFormat(new Number(5000)), '5,000'); - }); - - test('String: strRight', function() { - equal(_('This_is_a_test_string').strRight('_'), 'is_a_test_string'); - equal(_('This_is_a_test_string').strRight('string'), ''); - equal(_('This_is_a_test_string').strRight(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRight('-'), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); - equal(_('').strRight('foo'), ''); - equal(_(null).strRight('foo'), ''); - equal(_(undefined).strRight('foo'), ''); - equal(_(12345).strRight(2), '345'); - }); - - test('String: strRightBack', function() { - equal(_('This_is_a_test_string').strRightBack('_'), 'string'); - equal(_('This_is_a_test_string').strRightBack('string'), ''); - equal(_('This_is_a_test_string').strRightBack(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRightBack(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRightBack('-'), 'This_is_a_test_string'); - equal(_('').strRightBack('foo'), ''); - equal(_(null).strRightBack('foo'), ''); - equal(_(undefined).strRightBack('foo'), ''); - equal(_(12345).strRightBack(2), '345'); - }); - - test('String: strLeft', function() { - equal(_('This_is_a_test_string').strLeft('_'), 'This'); - equal(_('This_is_a_test_string').strLeft('This'), ''); - equal(_('This_is_a_test_string').strLeft(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeft(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeft('-'), 'This_is_a_test_string'); - equal(_('').strLeft('foo'), ''); - equal(_(null).strLeft('foo'), ''); - equal(_(undefined).strLeft('foo'), ''); - equal(_(123454321).strLeft(3), '12'); - }); - - test('String: strLeftBack', function() { - equal(_('This_is_a_test_string').strLeftBack('_'), 'This_is_a_test'); - equal(_('This_is_a_test_string').strLeftBack('This'), ''); - equal(_('This_is_a_test_string').strLeftBack(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeftBack(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeftBack('-'), 'This_is_a_test_string'); - equal(_('').strLeftBack('foo'), ''); - equal(_(null).strLeftBack('foo'), ''); - equal(_(undefined).strLeftBack('foo'), ''); - equal(_(123454321).strLeftBack(3), '123454'); - }); - - test('Strings: stripTags', function() { - equal(_('a link').stripTags(), 'a link'); - equal(_('a link - - - - - - - - -

    Underscore.string Test Suite

    -

    -

    -
      -
      -

      Underscore.string Speed Suite

      - -
      - - diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html deleted file mode 100644 index 9854c171..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_standalone.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - Underscore.strings Test Suite - - - - - - - - -

      Underscore.string Test Suite

      -

      -

      -
        - - diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js deleted file mode 100644 index 32252a3f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/arrays.js +++ /dev/null @@ -1,200 +0,0 @@ -$(document).ready(function() { - - module("Arrays"); - - test("first", function() { - equal(_.first([1,2,3]), 1, 'can pull out the first element of an array'); - equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); - equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); - equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); - equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); - var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); - equal(result, 4, 'works on an arguments object.'); - result = _.map([[1,2,3],[1,2,3]], _.first); - equal(result.join(','), '1,1', 'works well with _.map'); - result = (function() { return _.take([1,2,3], 2); })(); - equal(result.join(','), '1,2', 'aliased as take'); - - equal(_.first(null), undefined, 'handles nulls'); - }); - - test("rest", function() { - var numbers = [1, 2, 3, 4]; - equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); - equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); - equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); - var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); - equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.rest); - equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); - result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4); - equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object'); - }); - - test("initial", function() { - equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); - equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); - var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); - equal(result.join(", "), "1, 2, 3", 'initial works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.initial); - equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); - }); - - test("last", function() { - equal(_.last([1,2,3]), 3, 'can pull out the last element of an array'); - equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); - equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); - equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); - var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); - equal(result, 4, 'works on an arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.last); - equal(result.join(','), '3,3', 'works well with _.map'); - - equal(_.last(null), undefined, 'handles nulls'); - }); - - test("compact", function() { - equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); - var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); - equal(result, 3, 'works on an arguments object'); - }); - - test("flatten", function() { - if (window.JSON) { - var list = [1, [2], [3, [[[4]]]]]; - equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); - equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); - var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); - equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); - } - }); - - test("without", function() { - var list = [1, 2, 1, 0, 3, 1, 4]; - equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); - var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); - equal(result.join(', '), '2, 3, 4', 'works on an arguments object'); - - var list = [{one : 1}, {two : 2}]; - ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); - ok(_.without(list, list[0]).length == 1, 'ditto.'); - }); - - test("uniq", function() { - var list = [1, 2, 1, 3, 1, 4]; - equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); - - var list = [1, 1, 1, 2, 2, 3]; - equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); - - var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; - var iterator = function(value) { return value.name; }; - equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); - - var iterator = function(value) { return value +1; }; - var list = [1, 2, 2, 3, 4, 4]; - equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); - - var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); - equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); - }); - - test("intersection", function() { - var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; - equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); - equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); - var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); - equal(result.join(''), 'moe', 'works on an arguments object'); - }); - - test("union", function() { - var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); - equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); - - var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); - equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); - }); - - test("difference", function() { - var result = _.difference([1, 2, 3], [2, 30, 40]); - equal(result.join(' '), '1 3', 'takes the difference of two arrays'); - - var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); - equal(result.join(' '), '3 4', 'takes the difference of three arrays'); - }); - - test('zip', function() { - var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; - var stooges = _.zip(names, ages, leaders); - equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); - }); - - test('object', function() { - var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); - var shouldBe = {moe: 30, larry: 40, curly: 50}; - ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object'); - - result = _.object([['one', 1], ['two', 2], ['three', 3]]); - shouldBe = {one: 1, two: 2, three: 3}; - ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object'); - - var stooges = {moe: 30, larry: 40, curly: 50}; - ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object'); - - ok(_.isEqual(_.object(null), {}), 'handles nulls'); - }); - - test("indexOf", function() { - var numbers = [1, 2, 3]; - numbers.indexOf = null; - equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); - var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); - equal(result, 1, 'works on an arguments object'); - equal(_.indexOf(null, 2), -1, 'handles nulls properly'); - - var numbers = [10, 20, 30, 40, 50], num = 35; - var index = _.indexOf(numbers, num, true); - equal(index, -1, '35 is not in the list'); - - numbers = [10, 20, 30, 40, 50]; num = 40; - index = _.indexOf(numbers, num, true); - equal(index, 3, '40 is in the list'); - - numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; - index = _.indexOf(numbers, num, true); - equal(index, 1, '40 is in the list'); - - numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; - index = _.indexOf(numbers, 2, 5); - equal(index, 7, 'supports the fromIndex argument'); - }); - - test("lastIndexOf", function() { - var numbers = [1, 0, 1]; - equal(_.lastIndexOf(numbers, 1), 2); - - numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; - numbers.lastIndexOf = null; - equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); - equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); - var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); - equal(result, 5, 'works on an arguments object'); - equal(_.indexOf(null, 2), -1, 'handles nulls properly'); - - numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; - index = _.lastIndexOf(numbers, 2, 2); - equal(index, 1, 'supports the fromIndex argument'); - }); - - test("range", function() { - equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); - equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); - equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); - equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); - equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); - equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); - equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); - equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js deleted file mode 100644 index 16cf7bf5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/chaining.js +++ /dev/null @@ -1,59 +0,0 @@ -$(document).ready(function() { - - module("Chaining"); - - test("map/flatten/reduce", function() { - var lyrics = [ - "I'm a lumberjack and I'm okay", - "I sleep all night and I work all day", - "He's a lumberjack and he's okay", - "He sleeps all night and he works all day" - ]; - var counts = _(lyrics).chain() - .map(function(line) { return line.split(''); }) - .flatten() - .reduce(function(hash, l) { - hash[l] = hash[l] || 0; - hash[l]++; - return hash; - }, {}).value(); - ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); - }); - - test("select/reject/sortBy", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; - numbers = _(numbers).chain().select(function(n) { - return n % 2 == 0; - }).reject(function(n) { - return n % 4 == 0; - }).sortBy(function(n) { - return -n; - }).value(); - equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); - }); - - test("select/reject/sortBy in functional style", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; - numbers = _.chain(numbers).select(function(n) { - return n % 2 == 0; - }).reject(function(n) { - return n % 4 == 0; - }).sortBy(function(n) { - return -n; - }).value(); - equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); - }); - - test("reverse/concat/unshift/pop/map", function() { - var numbers = [1,2,3,4,5]; - numbers = _(numbers).chain() - .reverse() - .concat([5, 5, 5]) - .unshift(17) - .pop() - .map(function(n){ return n * 2; }) - .value(); - equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js deleted file mode 100644 index e089626d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/collections.js +++ /dev/null @@ -1,426 +0,0 @@ -$(document).ready(function() { - - module("Collections"); - - test("each", function() { - _.each([1, 2, 3], function(num, i) { - equal(num, i + 1, 'each iterators provide value and iteration count'); - }); - - var answers = []; - _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); - equal(answers.join(', '), '5, 10, 15', 'context object property accessed'); - - answers = []; - _.forEach([1, 2, 3], function(num){ answers.push(num); }); - equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); - - answers = []; - var obj = {one : 1, two : 2, three : 3}; - obj.constructor.prototype.four = 4; - _.each(obj, function(value, key){ answers.push(key); }); - equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); - delete obj.constructor.prototype.four; - - answer = null; - _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); - ok(answer, 'can reference the original collection from inside the iterator'); - - answers = 0; - _.each(null, function(){ ++answers; }); - equal(answers, 0, 'handles a null properly'); - }); - - test('map', function() { - var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'doubled numbers'); - - doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); - - var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); - equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); - - var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); - - if (document.querySelectorAll) { - var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); - } - - var ids = _.map($('#map-test').children(), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.'); - - var ids = _.map(document.images, function(n){ return n.id; }); - ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); - - var ifnull = _.map(null, function(){}); - ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); - }); - - test('reduce', function() { - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'can sum up an array'); - - var context = {multiplier : 3}; - sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); - equal(sum, 18, 'can reduce with a context object'); - - sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'aliased as "inject"'); - - sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'OO-style reduce'); - - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); - equal(sum, 6, 'default initial value'); - - var ifnull; - try { - _.reduce(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); - - ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); - }); - - test('reduceRight', function() { - var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equal(list, 'bazbarfoo', 'can perform right folds'); - - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equal(list, 'bazbarfoo', 'aliased as "foldr"'); - - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); - equal(list, 'bazbarfoo', 'default initial value'); - - var ifnull; - try { - _.reduceRight(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); - - var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; }); - equal(sum, 6, 'default initial value on object'); - - ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - - equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); - - // Assert that the correct arguments are being passed. - - var args, - memo = {}, - object = {a: 1, b: 2}, - lastKey = _.keys(object).pop(); - - var expected = lastKey == 'a' - ? [memo, 1, 'a', object] - : [memo, 2, 'b', object]; - - _.reduceRight(object, function() { - args || (args = _.toArray(arguments)); - }, memo); - - deepEqual(args, expected); - - // And again, with numeric keys. - - object = {'2': 'a', '1': 'b'}; - lastKey = _.keys(object).pop(); - args = null; - - expected = lastKey == '2' - ? [memo, 'a', '2', object] - : [memo, 'b', '1', object]; - - _.reduceRight(object, function() { - args || (args = _.toArray(arguments)); - }, memo); - - deepEqual(args, expected); - }); - - test('find', function() { - var array = [1, 2, 3, 4]; - strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); - strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); - }); - - test('detect', function() { - var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); - equal(result, 2, 'found the first "2" and broke the loop'); - }); - - test('select', function() { - var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(evens.join(', '), '2, 4, 6', 'selected each even number'); - - evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); - }); - - test('reject', function() { - var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); - - var context = "obj"; - - var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){ - equal(context, "obj"); - return num % 2 != 0; - }, context); - equal(evens.join(', '), '2, 4, 6', 'rejected each odd number'); - }); - - test('all', function() { - ok(_.all([], _.identity), 'the empty set'); - ok(_.all([true, true, true], _.identity), 'all true values'); - ok(!_.all([true, false, true], _.identity), 'one false value'); - ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); - ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); - ok(_.all([1], _.identity) === true, 'cast to boolean - true'); - ok(_.all([0], _.identity) === false, 'cast to boolean - false'); - ok(_.every([true, true, true], _.identity), 'aliased as "every"'); - ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined'); - }); - - test('any', function() { - var nativeSome = Array.prototype.some; - Array.prototype.some = null; - ok(!_.any([]), 'the empty set'); - ok(!_.any([false, false, false]), 'all false values'); - ok(_.any([false, false, true]), 'one true value'); - ok(_.any([null, 0, 'yes', false]), 'a string'); - ok(!_.any([null, 0, '', false]), 'falsy values'); - ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); - ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); - ok(_.any([1], _.identity) === true, 'cast to boolean - true'); - ok(_.any([0], _.identity) === false, 'cast to boolean - false'); - ok(_.some([false, false, true]), 'aliased as "some"'); - Array.prototype.some = nativeSome; - }); - - test('include', function() { - ok(_.include([1,2,3], 2), 'two is in the array'); - ok(!_.include([1,3,9], 2), 'two is not in the array'); - ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); - ok(_([1,2,3]).include(2), 'OO-style include'); - }); - - test('invoke', function() { - var list = [[5, 1, 7], [3, 2, 1]]; - var result = _.invoke(list, 'sort'); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); - }); - - test('invoke w/ function reference', function() { - var list = [[5, 1, 7], [3, 2, 1]]; - var result = _.invoke(list, Array.prototype.sort); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); - }); - - // Relevant when using ClojureScript - test('invoke when strings have a call method', function() { - String.prototype.call = function() { - return 42; - }; - var list = [[5, 1, 7], [3, 2, 1]]; - var s = "foo"; - equal(s.call(), 42, "call function exists"); - var result = _.invoke(list, 'sort'); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); - delete String.prototype.call; - equal(s.call, undefined, "call function removed"); - }); - - test('pluck', function() { - var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; - equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); - }); - - test('where', function() { - var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; - var result = _.where(list, {a: 1}); - equal(result.length, 3); - equal(result[result.length - 1].b, 4); - result = _.where(list, {b: 2}); - equal(result.length, 2); - equal(result[0].a, 1); - }); - - test('max', function() { - equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); - - var neg = _.max([1, 2, 3], function(num){ return -num; }); - equal(neg, 1, 'can perform a computation-based max'); - - equal(-Infinity, _.max({}), 'Maximum value of an empty object'); - equal(-Infinity, _.max([]), 'Maximum value of an empty array'); - - equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array"); - }); - - test('min', function() { - equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); - - var neg = _.min([1, 2, 3], function(num){ return -num; }); - equal(neg, 3, 'can perform a computation-based min'); - - equal(Infinity, _.min({}), 'Minimum value of an empty object'); - equal(Infinity, _.min([]), 'Minimum value of an empty array'); - - var now = new Date(9999999999); - var then = new Date(0); - equal(_.min([now, then]), then); - - equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array"); - }); - - test('sortBy', function() { - var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; - people = _.sortBy(people, function(person){ return person.age; }); - equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); - - var list = [undefined, 4, 1, undefined, 3, 2]; - equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values'); - - var list = ["one", "two", "three", "four", "five"]; - var sorted = _.sortBy(list, 'length'); - equal(sorted.join(' '), 'one two four five three', 'sorted by length'); - - function Pair(x, y) { - this.x = x; - this.y = y; - } - - var collection = [ - new Pair(1, 1), new Pair(1, 2), - new Pair(1, 3), new Pair(1, 4), - new Pair(1, 5), new Pair(1, 6), - new Pair(2, 1), new Pair(2, 2), - new Pair(2, 3), new Pair(2, 4), - new Pair(2, 5), new Pair(2, 6), - new Pair(undefined, 1), new Pair(undefined, 2), - new Pair(undefined, 3), new Pair(undefined, 4), - new Pair(undefined, 5), new Pair(undefined, 6) - ]; - - var actual = _.sortBy(collection, function(pair) { - return pair.x; - }); - - deepEqual(actual, collection, 'sortBy should be stable'); - }); - - test('groupBy', function() { - var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); - ok('0' in parity && '1' in parity, 'created a group for each value'); - equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); - - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; - var grouped = _.groupBy(list, 'length'); - equal(grouped['3'].join(' '), 'one two six ten'); - equal(grouped['4'].join(' '), 'four five nine'); - equal(grouped['5'].join(' '), 'three seven eight'); - - var context = {}; - _.groupBy([{}], function(){ ok(this === context); }, context); - - grouped = _.groupBy([4.2, 6.1, 6.4], function(num) { - return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; - }); - equal(grouped.constructor.length, 1); - equal(grouped.hasOwnProperty.length, 2); - - var array = [{}]; - _.groupBy(array, function(value, index, obj){ ok(obj === array); }); - }); - - test('countBy', function() { - var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); - equal(parity['true'], 2); - equal(parity['false'], 3); - - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; - var grouped = _.countBy(list, 'length'); - equal(grouped['3'], 4); - equal(grouped['4'], 3); - equal(grouped['5'], 3); - - var context = {}; - _.countBy([{}], function(){ ok(this === context); }, context); - - grouped = _.countBy([4.2, 6.1, 6.4], function(num) { - return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; - }); - equal(grouped.constructor, 1); - equal(grouped.hasOwnProperty, 2); - - var array = [{}]; - _.countBy(array, function(value, index, obj){ ok(obj === array); }); - }); - - test('sortedIndex', function() { - var numbers = [10, 20, 30, 40, 50], num = 35; - var indexForNum = _.sortedIndex(numbers, num); - equal(indexForNum, 3, '35 should be inserted at index 3'); - - var indexFor30 = _.sortedIndex(numbers, 30); - equal(indexFor30, 2, '30 should be inserted at index 2'); - - var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; - var iterator = function(obj){ return obj.x; }; - strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); - strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); - - var context = {1: 2, 2: 3, 3: 4}; - iterator = function(obj){ return this[obj]; }; - strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); - }); - - test('shuffle', function() { - var numbers = _.range(10); - var shuffled = _.shuffle(numbers).sort(); - notStrictEqual(numbers, shuffled, 'original object is unmodified'); - equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); - }); - - test('toArray', function() { - ok(!_.isArray(arguments), 'arguments object is not an array'); - ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); - var a = [1,2,3]; - ok(_.toArray(a) !== a, 'array is cloned'); - equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); - - var numbers = _.toArray({one : 1, two : 2, three : 3}); - equal(numbers.join(', '), '1, 2, 3', 'object flattened into array'); - }); - - test('size', function() { - equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); - equal(_.size([1, 2, 3]), 3, 'can compute the size of an array'); - - var func = function() { - return _.size(arguments); - }; - - equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); - - equal(_.size('hello'), 5, 'can compute the size of a string'); - - equal(_.size(null), 0, 'handles nulls'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js deleted file mode 100644 index a5296587..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/functions.js +++ /dev/null @@ -1,259 +0,0 @@ -$(document).ready(function() { - - module("Functions"); - - test("bind", function() { - var context = {name : 'moe'}; - var func = function(arg) { return "name: " + (this.name || arg); }; - var bound = _.bind(func, context); - equal(bound(), 'name: moe', 'can bind a function to a context'); - - bound = _(func).bind(context); - equal(bound(), 'name: moe', 'can do OO-style binding'); - - bound = _.bind(func, null, 'curly'); - equal(bound(), 'name: curly', 'can bind without specifying a context'); - - func = function(salutation, name) { return salutation + ': ' + name; }; - func = _.bind(func, this, 'hello'); - equal(func('moe'), 'hello: moe', 'the function was partially applied in advance'); - - var func = _.bind(func, this, 'curly'); - equal(func(), 'hello: curly', 'the function was completely applied in advance'); - - var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; - func = _.bind(func, this, 'hello', 'moe', 'curly'); - equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); - - func = function(context, message) { equal(this, context, message); }; - _.bind(func, 0, 0, 'can bind a function to `0`')(); - _.bind(func, '', '', 'can bind a function to an empty string')(); - _.bind(func, false, false, 'can bind a function to `false`')(); - - // These tests are only meaningful when using a browser without a native bind function - // To test this with a modern browser, set underscore's nativeBind to undefined - var F = function () { return this; }; - var Boundf = _.bind(F, {hello: "moe curly"}); - equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); - equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); - }); - - test("bindAll", function() { - var curly = {name : 'curly'}, moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } - }; - curly.getName = moe.getName; - _.bindAll(moe, 'getName', 'sayHi'); - curly.sayHi = moe.sayHi; - equal(curly.getName(), 'name: curly', 'unbound function is bound to current object'); - equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); - - curly = {name : 'curly'}; - moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } - }; - _.bindAll(moe); - curly.sayHi = moe.sayHi; - equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); - }); - - test("memoize", function() { - var fib = function(n) { - return n < 2 ? n : fib(n - 1) + fib(n - 2); - }; - var fastFib = _.memoize(fib); - equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); - equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); - - var o = function(str) { - return str; - }; - var fastO = _.memoize(o); - equal(o('toString'), 'toString', 'checks hasOwnProperty'); - equal(fastO('toString'), 'toString', 'checks hasOwnProperty'); - }); - - asyncTest("delay", 2, function() { - var delayed = false; - _.delay(function(){ delayed = true; }, 100); - setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); - setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); - }); - - asyncTest("defer", 1, function() { - var deferred = false; - _.defer(function(bool){ deferred = bool; }, true); - _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); - }); - - asyncTest("throttle", 2, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); throttledIncr(); throttledIncr(); - setTimeout(throttledIncr, 70); - setTimeout(throttledIncr, 120); - setTimeout(throttledIncr, 140); - setTimeout(throttledIncr, 190); - setTimeout(throttledIncr, 220); - setTimeout(throttledIncr, 240); - _.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30); - _.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400); - }); - - asyncTest("throttle arguments", 2, function() { - var value = 0; - var update = function(val){ value = val; }; - var throttledUpdate = _.throttle(update, 100); - throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); - setTimeout(function(){ throttledUpdate(4); }, 120); - setTimeout(function(){ throttledUpdate(5); }, 140); - setTimeout(function(){ throttledUpdate(6); }, 250); - _.delay(function(){ equal(value, 1, "updated to latest value"); }, 40); - _.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400); - }); - - asyncTest("throttle once", 2, function() { - var counter = 0; - var incr = function(){ return ++counter; }; - var throttledIncr = _.throttle(incr, 100); - var result = throttledIncr(); - _.delay(function(){ - equal(result, 1, "throttled functions return their value"); - equal(counter, 1, "incr was called once"); start(); - }, 220); - }); - - asyncTest("throttle twice", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); throttledIncr(); - _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220); - }); - - asyncTest("throttle repeatedly with results", 9, function() { - var counter = 0; - var incr = function(){ return ++counter; }; - var throttledIncr = _.throttle(incr, 100); - var results = []; - var saveResult = function() { results.push(throttledIncr()); }; - saveResult(); saveResult(); saveResult(); - setTimeout(saveResult, 70); - setTimeout(saveResult, 120); - setTimeout(saveResult, 140); - setTimeout(saveResult, 190); - setTimeout(saveResult, 240); - setTimeout(saveResult, 260); - _.delay(function() { - equal(results[0], 1, "incr was called once"); - equal(results[1], 1, "incr was throttled"); - equal(results[2], 1, "incr was throttled"); - equal(results[3], 1, "incr was throttled"); - equal(results[4], 2, "incr was called twice"); - equal(results[5], 2, "incr was throttled"); - equal(results[6], 2, "incr was throttled"); - equal(results[7], 3, "incr was called thrice"); - equal(results[8], 3, "incr was throttled"); - start(); - }, 400); - }); - - asyncTest("debounce", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var debouncedIncr = _.debounce(incr, 50); - debouncedIncr(); debouncedIncr(); debouncedIncr(); - setTimeout(debouncedIncr, 30); - setTimeout(debouncedIncr, 60); - setTimeout(debouncedIncr, 90); - setTimeout(debouncedIncr, 120); - setTimeout(debouncedIncr, 150); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); - }); - - asyncTest("debounce asap", 5, function() { - var a, b, c; - var counter = 0; - var incr = function(){ return ++counter; }; - var debouncedIncr = _.debounce(incr, 50, true); - a = debouncedIncr(); - b = debouncedIncr(); - c = debouncedIncr(); - equal(a, 1); - equal(b, 1); - equal(c, 1); - equal(counter, 1, 'incr was called immediately'); - setTimeout(debouncedIncr, 30); - setTimeout(debouncedIncr, 60); - setTimeout(debouncedIncr, 90); - setTimeout(debouncedIncr, 120); - setTimeout(debouncedIncr, 150); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); - }); - - asyncTest("debounce asap recursively", 2, function() { - var counter = 0; - var debouncedIncr = _.debounce(function(){ - counter++; - if (counter < 5) debouncedIncr(); - }, 50, true); - debouncedIncr(); - equal(counter, 1, 'incr was called immediately'); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70); - }); - - test("once", function() { - var num = 0; - var increment = _.once(function(){ num++; }); - increment(); - increment(); - equal(num, 1); - }); - - test("wrap", function() { - var greet = function(name){ return "hi: " + name; }; - var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); - equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); - - var inner = function(){ return "Hello "; }; - var obj = {name : "Moe"}; - obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); - equal(obj.hi(), "Hello Moe"); - - var noop = function(){}; - var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); - var ret = wrapped(['whats', 'your'], 'vector', 'victor'); - deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); - }); - - test("compose", function() { - var greet = function(name){ return "hi: " + name; }; - var exclaim = function(sentence){ return sentence + '!'; }; - var composed = _.compose(exclaim, greet); - equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); - - composed = _.compose(greet, exclaim); - equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); - }); - - test("after", function() { - var testAfter = function(afterAmount, timesCalled) { - var afterCalled = 0; - var after = _.after(afterAmount, function() { - afterCalled++; - }); - while (timesCalled--) after(); - return afterCalled; - }; - - equal(testAfter(5, 5), 1, "after(N) should fire after being called N times"); - equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); - equal(testAfter(0, 0), 1, "after(0) should fire immediately"); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html deleted file mode 100644 index 064fa986..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - Underscore Test Suite - - - - - - - - - - - - - - - - -
        -
        -
        -
        -
        -
        -
        -
        -

        Underscore Speed Suite

        -

        - A representative sample of the functions are benchmarked here, to provide - a sense of how fast they might run in different browsers. - Each iteration runs on an array of 1000 elements.

        - For example, the 'intersection' test measures the number of times you can - find the intersection of two thousand-element arrays in one second. -

        -
        - - - diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js deleted file mode 100644 index 22949c3b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/objects.js +++ /dev/null @@ -1,548 +0,0 @@ -$(document).ready(function() { - - module("Objects"); - - test("keys", function() { - equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); - // the test above is not safe because it relies on for-in enumeration order - var a = []; a[1] = 0; - equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); - raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values'); - raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values'); - raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives'); - raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives'); - raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives'); - }); - - test("values", function() { - equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object'); - equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"'); - }); - - test("pairs", function() { - deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); - deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); - }); - - test("invert", function() { - var obj = {first: 'Moe', second: 'Larry', third: 'Curly'}; - equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object'); - ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started'); - - var obj = {length: 3}; - ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"') - }); - - test("functions", function() { - var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; - ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); - - var Animal = function(){}; - Animal.prototype.run = function(){}; - equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); - }); - - test("extend", function() { - var result; - equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); - equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); - equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); - result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); - ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); - result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); - ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); - result = _.extend({}, {a: void 0, b: null}); - equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); - }); - - test("pick", function() { - var result; - result = _.pick({a:1, b:2, c:3}, 'a', 'c'); - ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named'); - result = _.pick({a:1, b:2, c:3}, ['b', 'c']); - ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array'); - result = _.pick({a:1, b:2, c:3}, ['a'], 'b'); - ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args'); - - var Obj = function(){}; - Obj.prototype = {a: 1, b: 2, c: 3}; - ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props'); - }); - - test("omit", function() { - var result; - result = _.omit({a:1, b:2, c:3}, 'b'); - ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property'); - result = _.omit({a:1, b:2, c:3}, 'a', 'c'); - ok(_.isEqual(result, {b:2}), 'can omit several named properties'); - result = _.omit({a:1, b:2, c:3}, ['b', 'c']); - ok(_.isEqual(result, {a:1}), 'can omit properties named in an array'); - - var Obj = function(){}; - Obj.prototype = {a: 1, b: 2, c: 3}; - ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props'); - }); - - test("defaults", function() { - var result; - var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; - - _.defaults(options, {zero: 1, one: 10, twenty: 20}); - equal(options.zero, 0, 'value exists'); - equal(options.one, 1, 'value exists'); - equal(options.twenty, 20, 'default applied'); - - _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); - equal(options.empty, "", 'value exists'); - ok(_.isNaN(options.nan), "NaN isn't overridden"); - equal(options.word, "word", 'new value is added, first one wins'); - }); - - test("clone", function() { - var moe = {name : 'moe', lucky : [13, 27, 34]}; - var clone = _.clone(moe); - equal(clone.name, 'moe', 'the clone as the attributes of the original'); - - clone.name = 'curly'; - ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); - - clone.lucky.push(101); - equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); - - equal(_.clone(undefined), void 0, 'non objects should not be changed by clone'); - equal(_.clone(1), 1, 'non objects should not be changed by clone'); - equal(_.clone(null), null, 'non objects should not be changed by clone'); - }); - - test("isEqual", function() { - function First() { - this.value = 1; - } - First.prototype.value = 1; - function Second() { - this.value = 1; - } - Second.prototype.value = 2; - - // Basic equality and identity comparisons. - ok(_.isEqual(null, null), "`null` is equal to `null`"); - ok(_.isEqual(), "`undefined` is equal to `undefined`"); - - ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); - ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); - ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); - ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); - - // String object and primitive comparisons. - ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); - ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); - ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); - ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); - - ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); - ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); - ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); - - // Number object and primitive comparisons. - ok(_.isEqual(75, 75), "Identical number primitives are equal"); - ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); - ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); - ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); - ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); - - ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); - ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); - - // Comparisons involving `NaN`. - ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); - ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); - ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); - ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); - - // Boolean object and primitive comparisons. - ok(_.isEqual(true, true), "Identical boolean primitives are equal"); - ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); - ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); - ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); - - // Common type coercions. - ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); - ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); - ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); - ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); - ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); - ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); - ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); - ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); - ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); - - // Dates. - ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); - ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); - ok(!_.isEqual(new Date(2009, 11, 13), { - getTime: function(){ - return 12606876e5; - } - }), "Date objects and objects with a `getTime` method are not equal"); - ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); - - // Functions. - ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); - - // RegExps. - ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); - ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); - ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); - ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); - ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); - - // Empty arrays, array-like objects, and object literals. - ok(_.isEqual({}, {}), "Empty object literals are equal"); - ok(_.isEqual([], []), "Empty array literals are equal"); - ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); - ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); - ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); - - ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); - ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); - - // Arrays with primitive and object values. - ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); - ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); - - // Multi-dimensional arrays. - var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); - - // Overwrite the methods defined in ES 5.1 section 15.4.4. - a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; - b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; - - // Array elements and properties. - ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); - a.push("White Rocks"); - ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); - a.push("East Boulder"); - b.push("Gunbarrel Ranch", "Teller Farm"); - ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); - - // Sparse arrays. - ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); - ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); - - // Simple objects. - ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); - ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); - ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); - ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); - ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); - - // `A` contains nested objects and arrays. - a = { - name: new String("Moe Howard"), - age: new Number(77), - stooge: true, - hobbies: ["acting"], - film: { - name: "Sing a Song of Six Pants", - release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], - minutes: new Number(16), - seconds: 54 - } - }; - - // `B` contains equivalent nested objects and arrays. - b = { - name: new String("Moe Howard"), - age: new Number(77), - stooge: true, - hobbies: ["acting"], - film: { - name: "Sing a Song of Six Pants", - release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], - minutes: new Number(16), - seconds: 54 - } - }; - ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); - - // Instances. - ok(_.isEqual(new First, new First), "Object instances are equal"); - ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); - ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); - ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); - - // Circular Arrays. - (a = []).push(a); - (b = []).push(b); - ok(_.isEqual(a, b), "Arrays containing circular references are equal"); - a.push(new String("Larry")); - b.push(new String("Larry")); - ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); - a.push("Shemp"); - b.push("Curly"); - ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); - - // More circular arrays #767. - a = ["everything is checked but", "this", "is not"]; - a[1] = a; - b = ["everything is checked but", ["this", "array"], "is not"]; - ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal"); - - // Circular Objects. - a = {abc: null}; - b = {abc: null}; - a.abc = a; - b.abc = b; - ok(_.isEqual(a, b), "Objects containing circular references are equal"); - a.def = 75; - b.def = 75; - ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); - a.def = new Number(75); - b.def = new Number(63); - ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); - - // More circular objects #767. - a = {everything: "is checked", but: "this", is: "not"}; - a.but = a; - b = {everything: "is checked", but: {that:"object"}, is: "not"}; - ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal"); - - // Cyclic Structures. - a = [{abc: null}]; - b = [{abc: null}]; - (a[0].abc = a).push(a); - (b[0].abc = b).push(b); - ok(_.isEqual(a, b), "Cyclic structures are equal"); - a[0].def = "Larry"; - b[0].def = "Larry"; - ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); - a[0].def = new String("Larry"); - b[0].def = new String("Curly"); - ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); - - // Complex Circular References. - a = {foo: {b: {foo: {c: {foo: null}}}}}; - b = {foo: {b: {foo: {c: {foo: null}}}}}; - a.foo.b.foo.c.foo = a; - b.foo.b.foo.c.foo = b; - ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); - - // Chaining. - ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); - equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); - - // Custom `isEqual` methods. - var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; - var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; - - ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); - ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); - ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); - ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); - - // Objects from another frame. - ok(_.isEqual({}, iObject)); - }); - - test("isEmpty", function() { - ok(!_([1]).isEmpty(), '[1] is not empty'); - ok(_.isEmpty([]), '[] is empty'); - ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); - ok(_.isEmpty({}), '{} is empty'); - ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); - ok(_.isEmpty(null), 'null is empty'); - ok(_.isEmpty(), 'undefined is empty'); - ok(_.isEmpty(''), 'the empty string is empty'); - ok(!_.isEmpty('moe'), 'but other strings are not'); - - var obj = {one : 1}; - delete obj.one; - ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); - }); - - // Setup remote variables for iFrame tests. - var iframe = document.createElement('iframe'); - jQuery(iframe).appendTo(document.body); - var iDoc = iframe.contentDocument || iframe.contentWindow.document; - iDoc.write( - "" - ); - iDoc.close(); - - test("isElement", function() { - ok(!_.isElement('div'), 'strings are not dom elements'); - ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); - ok(_.isElement(iElement), 'even from another frame'); - }); - - test("isArguments", function() { - var args = (function(){ return arguments; })(1, 2, 3); - ok(!_.isArguments('string'), 'a string is not an arguments object'); - ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); - ok(_.isArguments(args), 'but the arguments object is an arguments object'); - ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); - ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); - ok(_.isArguments(iArguments), 'even from another frame'); - }); - - test("isObject", function() { - ok(_.isObject(arguments), 'the arguments object is object'); - ok(_.isObject([1, 2, 3]), 'and arrays'); - ok(_.isObject($('html')[0]), 'and DOM element'); - ok(_.isObject(iElement), 'even from another frame'); - ok(_.isObject(function () {}), 'and functions'); - ok(_.isObject(iFunction), 'even from another frame'); - ok(!_.isObject(null), 'but not null'); - ok(!_.isObject(undefined), 'and not undefined'); - ok(!_.isObject('string'), 'and not string'); - ok(!_.isObject(12), 'and not number'); - ok(!_.isObject(true), 'and not boolean'); - ok(_.isObject(new String('string')), 'but new String()'); - }); - - test("isArray", function() { - ok(!_.isArray(arguments), 'the arguments object is not an array'); - ok(_.isArray([1, 2, 3]), 'but arrays are'); - ok(_.isArray(iArray), 'even from another frame'); - }); - - test("isString", function() { - ok(!_.isString(document.body), 'the document body is not a string'); - ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); - ok(_.isString(iString), 'even from another frame'); - }); - - test("isNumber", function() { - ok(!_.isNumber('string'), 'a string is not a number'); - ok(!_.isNumber(arguments), 'the arguments object is not a number'); - ok(!_.isNumber(undefined), 'undefined is not a number'); - ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); - ok(_.isNumber(NaN), 'NaN *is* a number'); - ok(_.isNumber(Infinity), 'Infinity is a number'); - ok(_.isNumber(iNumber), 'even from another frame'); - ok(!_.isNumber('1'), 'numeric strings are not numbers'); - }); - - test("isBoolean", function() { - ok(!_.isBoolean(2), 'a number is not a boolean'); - ok(!_.isBoolean("string"), 'a string is not a boolean'); - ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); - ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); - ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); - ok(!_.isBoolean(undefined), 'undefined is not a boolean'); - ok(!_.isBoolean(NaN), 'NaN is not a boolean'); - ok(!_.isBoolean(null), 'null is not a boolean'); - ok(_.isBoolean(true), 'but true is'); - ok(_.isBoolean(false), 'and so is false'); - ok(_.isBoolean(iBoolean), 'even from another frame'); - }); - - test("isFunction", function() { - ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); - ok(!_.isFunction('moe'), 'strings are not functions'); - ok(_.isFunction(_.isFunction), 'but functions are'); - ok(_.isFunction(iFunction), 'even from another frame'); - }); - - test("isDate", function() { - ok(!_.isDate(100), 'numbers are not dates'); - ok(!_.isDate({}), 'objects are not dates'); - ok(_.isDate(new Date()), 'but dates are'); - ok(_.isDate(iDate), 'even from another frame'); - }); - - test("isRegExp", function() { - ok(!_.isRegExp(_.identity), 'functions are not RegExps'); - ok(_.isRegExp(/identity/), 'but RegExps are'); - ok(_.isRegExp(iRegExp), 'even from another frame'); - }); - - test("isFinite", function() { - ok(!_.isFinite(undefined), 'undefined is not Finite'); - ok(!_.isFinite(null), 'null is not Finite'); - ok(!_.isFinite(NaN), 'NaN is not Finite'); - ok(!_.isFinite(Infinity), 'Infinity is not Finite'); - ok(!_.isFinite(-Infinity), '-Infinity is not Finite'); - ok(!_.isFinite('12'), 'Strings are not numbers'); - var obj = new Number(5); - ok(_.isFinite(obj), 'Number instances can be finite'); - ok(_.isFinite(0), '0 is Finite'); - ok(_.isFinite(123), 'Ints are Finite'); - ok(_.isFinite(-12.44), 'Floats are Finite'); - }); - - test("isNaN", function() { - ok(!_.isNaN(undefined), 'undefined is not NaN'); - ok(!_.isNaN(null), 'null is not NaN'); - ok(!_.isNaN(0), '0 is not NaN'); - ok(_.isNaN(NaN), 'but NaN is'); - ok(_.isNaN(iNaN), 'even from another frame'); - ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); - }); - - test("isNull", function() { - ok(!_.isNull(undefined), 'undefined is not null'); - ok(!_.isNull(NaN), 'NaN is not null'); - ok(_.isNull(null), 'but null is'); - ok(_.isNull(iNull), 'even from another frame'); - }); - - test("isUndefined", function() { - ok(!_.isUndefined(1), 'numbers are defined'); - ok(!_.isUndefined(null), 'null is defined'); - ok(!_.isUndefined(false), 'false is defined'); - ok(!_.isUndefined(NaN), 'NaN is defined'); - ok(_.isUndefined(), 'nothing is undefined'); - ok(_.isUndefined(undefined), 'undefined is undefined'); - ok(_.isUndefined(iUndefined), 'even from another frame'); - }); - - if (window.ActiveXObject) { - test("IE host objects", function() { - var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); - ok(!_.isNumber(xml)); - ok(!_.isBoolean(xml)); - ok(!_.isNaN(xml)); - ok(!_.isFunction(xml)); - ok(!_.isNull(xml)); - ok(!_.isUndefined(xml)); - }); - } - - test("tap", function() { - var intercepted = null; - var interceptor = function(obj) { intercepted = obj; }; - var returned = _.tap(1, interceptor); - equal(intercepted, 1, "passes tapped object to interceptor"); - equal(returned, 1, "returns tapped object"); - - returned = _([1,2,3]).chain(). - map(function(n){ return n * 2; }). - max(). - tap(interceptor). - value(); - ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); - }); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js deleted file mode 100644 index 05e3f2a3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/speed.js +++ /dev/null @@ -1,75 +0,0 @@ -(function() { - - var numbers = []; - for (var i=0; i<1000; i++) numbers.push(i); - var objects = _.map(numbers, function(n){ return {num : n}; }); - var randomized = _.sortBy(numbers, function(){ return Math.random(); }); - var deep = _.map(_.range(100), function() { return _.range(1000); }); - - JSLitmus.test('_.each()', function() { - var timesTwo = []; - _.each(numbers, function(num){ timesTwo.push(num * 2); }); - return timesTwo; - }); - - JSLitmus.test('_(list).each()', function() { - var timesTwo = []; - _(numbers).each(function(num){ timesTwo.push(num * 2); }); - return timesTwo; - }); - - JSLitmus.test('jQuery.each()', function() { - var timesTwo = []; - jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); - return timesTwo; - }); - - JSLitmus.test('_.map()', function() { - return _.map(objects, function(obj){ return obj.num; }); - }); - - JSLitmus.test('jQuery.map()', function() { - return jQuery.map(objects, function(obj){ return obj.num; }); - }); - - JSLitmus.test('_.pluck()', function() { - return _.pluck(objects, 'num'); - }); - - JSLitmus.test('_.uniq()', function() { - return _.uniq(randomized); - }); - - JSLitmus.test('_.uniq() (sorted)', function() { - return _.uniq(numbers, true); - }); - - JSLitmus.test('_.sortBy()', function() { - return _.sortBy(numbers, function(num){ return -num; }); - }); - - JSLitmus.test('_.isEqual()', function() { - return _.isEqual(numbers, randomized); - }); - - JSLitmus.test('_.keys()', function() { - return _.keys(objects); - }); - - JSLitmus.test('_.values()', function() { - return _.values(objects); - }); - - JSLitmus.test('_.intersection()', function() { - return _.intersection(numbers, randomized); - }); - - JSLitmus.test('_.range()', function() { - return _.range(1000); - }); - - JSLitmus.test('_.flatten()', function() { - return _.flatten(deep); - }); - -})(); diff --git a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js b/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js deleted file mode 100644 index c9be20ad..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/grunt-legacy-log/node_modules/underscore.string/test/test_underscore/utility.js +++ /dev/null @@ -1,249 +0,0 @@ -$(document).ready(function() { - - var templateSettings; - - module("Utility", { - - setup: function() { - templateSettings = _.clone(_.templateSettings); - }, - - teardown: function() { - _.templateSettings = templateSettings; - } - - }); - - test("#750 - Return _ instance.", 2, function() { - var instance = _([]); - ok(_(instance) === instance); - ok(new _(instance) === instance); - }); - - test("identity", function() { - var moe = {name : 'moe'}; - equal(_.identity(moe), moe, 'moe is the same as his identity'); - }); - - test("uniqueId", function() { - var ids = [], i = 0; - while(i++ < 100) ids.push(_.uniqueId()); - equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); - }); - - test("times", function() { - var vals = []; - _.times(3, function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); - // - vals = []; - _(3).times(function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); - }); - - test("mixin", function() { - _.mixin({ - myReverse: function(string) { - return string.split('').reverse().join(''); - } - }); - equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); - equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); - }); - - test("_.escape", function() { - equal(_.escape("Curly & Moe"), "Curly & Moe"); - equal(_.escape("Curly & Moe"), "Curly &amp; Moe"); - equal(_.escape(null), ''); - }); - - test("_.unescape", function() { - var string = "Curly & Moe"; - equal(_.unescape("Curly & Moe"), string); - equal(_.unescape("Curly &amp; Moe"), "Curly & Moe"); - equal(_.unescape(null), ''); - equal(_.unescape(_.escape(string)), string); - }); - - test("template", function() { - var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); - var result = basicTemplate({thing : 'This'}); - equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); - - var sansSemicolonTemplate = _.template("A <% this %> B"); - equal(sansSemicolonTemplate(), "A B"); - - var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); - equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); - - var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); - equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); - - var fancyTemplate = _.template("
          <% \ - for (key in people) { \ - %>
        • <%= people[key] %>
        • <% } %>
        "); - result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); - equal(result, "
        • Moe
        • Larry
        • Curly
        ", 'can run arbitrary javascript in templates'); - - var escapedCharsInJavascriptTemplate = _.template("
          <% _.each(numbers.split('\\n'), function(item) { %>
        • <%= item %>
        • <% }) %>
        "); - result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); - equal(result, "
        • one
        • two
        • three
        • four
        ", 'Can use escaped characters (e.g. \\n) in Javascript'); - - var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
        \">
        <% }); %>"); - result = namespaceCollisionTemplate({ - pageCount: 3, - thumbnails: { - 1: "p1-thumbnail.gif", - 2: "p2-thumbnail.gif", - 3: "p3-thumbnail.gif" - } - }); - equal(result, "3 p3-thumbnail.gif
        "); - - var noInterpolateTemplate = _.template("

        Just some text. Hey, I know this is silly but it aids consistency.

        "); - result = noInterpolateTemplate(); - equal(result, "

        Just some text. Hey, I know this is silly but it aids consistency.

        "); - - var quoteTemplate = _.template("It's its, not it's"); - equal(quoteTemplate({}), "It's its, not it's"); - - var quoteInStatementAndBody = _.template("<%\ - if(foo == 'bar'){ \ - %>Statement quotes and 'quotes'.<% } %>"); - equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); - - var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); - equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); - - var template = _.template("<%- value %>"); - var result = template({value: " - -``` - -In the browser, you can attach Hooker's methods to any object. - -```html - - - -``` - -## Documentation - -### hooker.hook -Monkey-patch (hook) one or more methods of an object. -#### Signature: -`hooker.hook(object, [ props, ] [options | prehookFunction])` -#### `props` -The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all enumerable methods of `object` will be hooked. -#### `options` -* `pre` - (Function) a pre-hook function to be executed before the original function. Arguments passed into the method will be passed into the pre-hook function as well. -* `post` - (Function) a post-hook function to be executed after the original function. The original function's result is passed into the post-hook function as its first argument, followed by the method arguments. -* `once` - (Boolean) if true, auto-unhook the function after the first execution. -* `passName` - (Boolean) if true, pass the name of the method into the pre-hook function as its first arg (preceding all other arguments), and into the post-hook function as the second arg (after result but preceding all other arguments). - -#### Returns: -An array of hooked method names. - -### hooker.unhook -Un-monkey-patch (unhook) one or more methods of an object. -#### Signature: -`hooker.unhook(object [, props ])` -#### `props` -The optional `props` argument can be a method name, array of method names or null. If null (or omitted), all methods of `object` will be unhooked. -#### Returns: -An array of unhooked method names. - -### hooker.orig -Get a reference to the original method from a hooked function. -#### Signature: -`hooker.orig(object, props)` - -### hooker.override -When a pre- or post-hook returns the result of this function, the value -passed will be used in place of the original function's return value. Any -post-hook override value will take precedence over a pre-hook override value. -#### Signature: -`hooker.override(value)` - -### hooker.preempt -When a pre-hook returns the result of this function, the value passed will -be used in place of the original function's return value, and the original -function will NOT be executed. -#### Signature: -`hooker.preempt(value)` - -### hooker.filter -When a pre-hook returns the result of this function, the context and -arguments passed will be applied into the original function. -#### Signature: -`hooker.filter(context, arguments)` - - -## Examples -See the unit tests for more examples. - -```javascript -var hooker = require('hooker'); -// Simple logging. -hooker.hook(Math, "max", function() { - console.log(arguments.length + " arguments passed"); -}); -Math.max(5, 6, 7) // logs: "3 arguments passed", returns 7 - -hooker.unhook(Math, "max"); // (This is assumed between all further examples) -Math.max(5, 6, 7) // 7 - -// Returning hooker.override(value) overrides the original value. -hooker.hook(Math, "max", function() { - if (arguments.length === 0) { - return hooker.override(9000); - } -}); -Math.max(5, 6, 7) // 7 -Math.max() // 9000 - -// Auto-unhook after one execution. -hooker.hook(Math, "max", { - once: true, - pre: function() { - console.log("Init something here"); - } -}); -Math.max(5, 6, 7) // logs: "Init something here", returns 7 -Math.max(5, 6, 7) // 7 - -// Filter `this` and arguments through a pre-hook function. -hooker.hook(Math, "max", { - pre: function() { - var args = [].map.call(arguments, function(num) { - return num * 2; - }); - return hooker.filter(this, args); // thisValue, arguments - } -}); -Math.max(5, 6, 7) // 14 - -// Modify the original function's result with a post-hook function. -hooker.hook(Math, "max", { - post: function(result) { - return hooker.override(result * 100); - } -}); -Math.max(5, 6, 7) // 700 - -// Hook every Math method. Note: if Math's methods were enumerable, the second -// argument could be omitted. Since they aren't, an array of properties to hook -// must be explicitly passed. Non-method properties will be skipped. -// See a more generic example here: http://bit.ly/vvJlrS -hooker.hook(Math, Object.getOwnPropertyNames(Math), { - passName: true, - pre: function(name) { - console.log("=> Math." + name, [].slice.call(arguments, 1)); - }, - post: function(result, name) { - console.log("<= Math." + name, result); - } -}); - -var result = Math.max(5, 6, 7); -// => Math.max [ 5, 6, 7 ] -// <= Math.max 7 -result // 7 - -result = Math.ceil(3.456); -// => Math.ceil [ 3.456 ] -// <= Math.ceil 4 -result // 4 -``` - -## Contributing -In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/cowboy/grunt). - -_Also, please don't edit files in the "dist" subdirectory as they are generated via grunt. You'll find source code in the "lib" subdirectory!_ - -## Release History -2012/01/09 - v0.2.3 - First official release. - -## License -Copyright (c) 2012 "Cowboy" Ben Alman -Licensed under the MIT license. - diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/child.js b/spec/fixture/node_modules/grunt/node_modules/hooker/child.js deleted file mode 100644 index ae7dcf2f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/child.js +++ /dev/null @@ -1,101 +0,0 @@ -var path = require('path'); -var fs = require('fs'); -var nodeunit = require('nodeunit'); - -var filepaths = fs.readdirSync('test').map(function(filename) { - return path.join('test', filename); -}); - -var unfinished = {}; -var currentModule; -function sendMessage(message) { - process.stdout.write(JSON.stringify(message) + '\n'); -} - -// If an exception is thrown, let the parent process know and exit. -process.on('uncaughtException', function (e) { - sendMessage({error: [e.name, e.message, e.stack]}); - process.exit(); -}); - -// If Nodeunit explodes because a test was missing test.done(), handle it. -var unfinished = {}; -process.on('exit', function (e) { - var len = Object.keys(unfinished).length - if (len > 0) { - sendMessage({exit: ['UNFINISHED']}); - // process.reallyExit(len); - } else { - sendMessage({exit: ['finished']}); - } - // process.exit(); -}); - -nodeunit.reporters.test = { - run: function(files, options, callback) { - // Nodeunit needs absolute paths. - var paths = files.map(function (filepath) { - return path.resolve(filepath); - }); - nodeunit.runFiles(paths, { - // No idea. - testspec: undefined, - // Executed when the first test in a file is run. If no tests exist in - // the file, this doesn't execute. - moduleStart: function(name) { - // Keep track of this so that moduleDone output can be suppressed in - // cases where a test file contains no tests. - currentModule = name; - // Send back to the parent process. - sendMessage({moduleStart: [name.toString()]}); - }, - // Executed after a file is done being processed. This executes whether - // tests exist in the file or not. - moduleDone: function(name) { - // Abort if no tests actually ran. - if (name !== currentModule) { return; } - // Send back to the parent process. - sendMessage({moduleDone: [name.toString()]}); - }, - // Executed before each test is run. - testStart: function(name) { - // Keep track of the current test, in case test.done() was omitted - // and Nodeunit explodes. - unfinished[name] = name; - // Send back to the parent process. - sendMessage({testStart: [name.toString()]}); - }, - // Executed after each test and all its assertions are run. - testDone: function(name, assertions) { - delete unfinished[name]; - // Send back to the parent process. - sendMessage({testDone: [ - name.toString(), - assertions.failures(), - assertions.map(function(assertion) { - var e = assertion.error; - if (e) { - assertion.error = { - name: e.name, - message: e.message, - stack: e.stack - }; - } - return assertion; - }) - ]}); - }, - // Executed when everything is all done. - done: function (assertions) { - // Send back to the parent process. - sendMessage({done: [ - assertions.failures(), - assertions.duration, - assertions - ]}); - } - }); - } -} - -nodeunit.reporters.test.run(filepaths, {}); diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.js b/spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.js deleted file mode 100644 index d10a3216..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.js +++ /dev/null @@ -1,169 +0,0 @@ -/*! JavaScript Hooker - v0.2.3 - 1/29/2012 -* http://github.com/cowboy/javascript-hooker -* Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */ - -(function(exports) { - // Get an array from an array-like object with slice.call(arrayLikeObject). - var slice = [].slice; - // Get an "[object [[Class]]]" string with toString.call(value). - var toString = {}.toString; - - // I can't think of a better way to ensure a value is a specific type other - // than to create instances and use the `instanceof` operator. - function HookerOverride(v) { this.value = v; } - function HookerPreempt(v) { this.value = v; } - function HookerFilter(c, a) { this.context = c; this.args = a; } - - // When a pre- or post-hook returns the result of this function, the value - // passed will be used in place of the original function's return value. Any - // post-hook override value will take precedence over a pre-hook override - // value. - exports.override = function(value) { - return new HookerOverride(value); - }; - - // When a pre-hook returns the result of this function, the value passed will - // be used in place of the original function's return value, and the original - // function will NOT be executed. - exports.preempt = function(value) { - return new HookerPreempt(value); - }; - - // When a pre-hook returns the result of this function, the context and - // arguments passed will be applied into the original function. - exports.filter = function(context, args) { - return new HookerFilter(context, args); - }; - - // Execute callback(s) for properties of the specified object. - function forMethods(obj, props, callback) { - var prop; - if (typeof props === "string") { - // A single prop string was passed. Create an array. - props = [props]; - } else if (props == null) { - // No props were passed, so iterate over all properties, building an - // array. Unfortunately, Object.keys(obj) doesn't work everywhere yet, so - // this has to be done manually. - props = []; - for (prop in obj) { - if (obj.hasOwnProperty(prop)) { - props.push(prop); - } - } - } - // Execute callback for every method in the props array. - var i = props.length; - while (i--) { - // If the property isn't a function... - if (toString.call(obj[props[i]]) !== "[object Function]" || - // ...or the callback returns false... - callback(obj, props[i]) === false) { - // ...remove it from the props array to be returned. - props.splice(i, 1); - } - } - // Return an array of method names for which the callback didn't fail. - return props; - } - - // Monkey-patch (hook) a method of an object. - exports.hook = function(obj, props, options) { - // If the props argument was omitted, shuffle the arguments. - if (options == null) { - options = props; - props = null; - } - // If just a function is passed instead of an options hash, use that as a - // pre-hook function. - if (typeof options === "function") { - options = {pre: options}; - } - - // Hook the specified method of the object. - return forMethods(obj, props, function(obj, prop) { - // The original (current) method. - var orig = obj[prop]; - // The new hooked function. - function hooked() { - var result, origResult, tmp; - - // Get an array of arguments. - var args = slice.call(arguments); - - // If passName option is specified, prepend prop to the args array, - // passing it as the first argument to any specified hook functions. - if (options.passName) { - args.unshift(prop); - } - - // If a pre-hook function was specified, invoke it in the current - // context with the passed-in arguments, and store its result. - if (options.pre) { - result = options.pre.apply(this, args); - } - - if (result instanceof HookerFilter) { - // If the pre-hook returned hooker.filter(context, args), invoke the - // original function with that context and arguments, and store its - // result. - origResult = result = orig.apply(result.context, result.args); - } else if (result instanceof HookerPreempt) { - // If the pre-hook returned hooker.preempt(value) just use the passed - // value and don't execute the original function. - origResult = result = result.value; - } else { - // Invoke the original function in the current context with the - // passed-in arguments, and store its result. - origResult = orig.apply(this, arguments); - // If the pre-hook returned hooker.override(value), use the passed - // value, otherwise use the original function's result. - result = result instanceof HookerOverride ? result.value : origResult; - } - - if (options.post) { - // If a post-hook function was specified, invoke it in the current - // context, passing in the result of the original function as the - // first argument, followed by any passed-in arguments. - tmp = options.post.apply(this, [origResult].concat(args)); - if (tmp instanceof HookerOverride) { - // If the post-hook returned hooker.override(value), use the passed - // value, otherwise use the previously computed result. - result = tmp.value; - } - } - - // Unhook if the "once" option was specified. - if (options.once) { - exports.unhook(obj, prop); - } - - // Return the result! - return result; - } - // Re-define the method. - obj[prop] = hooked; - // Fail if the function couldn't be hooked. - if (obj[prop] !== hooked) { return false; } - // Store a reference to the original method as a property on the new one. - obj[prop]._orig = orig; - }); - }; - - // Get a reference to the original method from a hooked function. - exports.orig = function(obj, prop) { - return obj[prop]._orig; - }; - - // Un-monkey-patch (unhook) a method of an object. - exports.unhook = function(obj, props) { - return forMethods(obj, props, function(obj, prop) { - // Get a reference to the original method, if it exists. - var orig = exports.orig(obj, prop); - // If there's no original method, it can't be unhooked, so fail. - if (!orig) { return false; } - // Unhook the method. - obj[prop] = orig; - }); - }; -}(typeof exports === "object" && exports || this)); diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.min.js b/spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.min.js deleted file mode 100644 index 2bcdb549..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/dist/ba-hooker.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! JavaScript Hooker - v0.2.3 - 1/29/2012 -* http://github.com/cowboy/javascript-hooker -* Copyright (c) 2012 "Cowboy" Ben Alman; Licensed MIT */ -(function(a){function d(a){this.value=a}function e(a){this.value=a}function f(a,b){this.context=a,this.args=b}function g(a,b,d){var e;if(typeof b=="string")b=[b];else if(b==null){b=[];for(e in a)a.hasOwnProperty(e)&&b.push(e)}var f=b.length;while(f--)(c.call(a[b[f]])!=="[object Function]"||d(a,b[f])===!1)&&b.splice(f,1);return b}var b=[].slice,c={}.toString;a.override=function(a){return new d(a)},a.preempt=function(a){return new e(a)},a.filter=function(a,b){return new f(a,b)},a.hook=function(c,h,i){return i==null&&(i=h,h=null),typeof i=="function"&&(i={pre:i}),g(c,h,function(c,g){function j(){var j,k,l,m=b.call(arguments);return i.passName&&m.unshift(g),i.pre&&(j=i.pre.apply(this,m)),j instanceof f?k=j=h.apply(j.context,j.args):j instanceof e?k=j=j.value:(k=h.apply(this,arguments),j=j instanceof d?j.value:k),i.post&&(l=i.post.apply(this,[k].concat(m)),l instanceof d&&(j=l.value)),i.once&&a.unhook(c,g),j}var h=c[g];c[g]=j;if(c[g]!==j)return!1;c[g]._orig=h})},a.orig=function(a,b){return a[b]._orig},a.unhook=function(b,c){return g(b,c,function(b,c){var d=a.orig(b,c);if(!d)return!1;b[c]=d})}})(typeof exports=="object"&&exports||this) \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/grunt.js b/spec/fixture/node_modules/grunt/node_modules/hooker/grunt.js deleted file mode 100644 index c6951485..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/grunt.js +++ /dev/null @@ -1,47 +0,0 @@ -/*global config:true, task:true*/ -config.init({ - pkg: '', - meta: { - name: 'JavaScript Hooker', - banner: '/*! <%= meta.name %> - v<%= pkg.version %> - <%= template.today("m/d/yyyy") %>\n' + - '* <%= pkg.homepage %>\n' + - '* Copyright (c) <%= template.today("yyyy") %> <%= pkg.author.name %>;' + - ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */' - }, - concat: { - 'dist/ba-hooker.js': ['', ''] - }, - min: { - 'dist/ba-hooker.min.js': ['', 'dist/ba-hooker.js'] - }, - test: { - files: ['test/**/*.js'] - }, - lint: { - files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js'] - }, - watch: { - files: '', - tasks: 'lint:files test:files' - }, - jshint: { - options: { - curly: true, - eqeqeq: true, - immed: true, - latedef: true, - newcap: true, - noarg: true, - sub: true, - undef: true, - eqnull: true - }, - globals: { - exports: true - } - }, - uglify: {} -}); - -// Default task. -task.registerTask('default', 'lint:files test:files concat min'); diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/lib/hooker.js b/spec/fixture/node_modules/grunt/node_modules/hooker/lib/hooker.js deleted file mode 100644 index 1ff9764b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/lib/hooker.js +++ /dev/null @@ -1,174 +0,0 @@ -/* - * JavaScript Hooker - * http://github.com/cowboy/javascript-hooker - * - * Copyright (c) 2012 "Cowboy" Ben Alman - * Licensed under the MIT license. - * http://benalman.com/about/license/ - */ - -(function(exports) { - // Get an array from an array-like object with slice.call(arrayLikeObject). - var slice = [].slice; - // Get an "[object [[Class]]]" string with toString.call(value). - var toString = {}.toString; - - // I can't think of a better way to ensure a value is a specific type other - // than to create instances and use the `instanceof` operator. - function HookerOverride(v) { this.value = v; } - function HookerPreempt(v) { this.value = v; } - function HookerFilter(c, a) { this.context = c; this.args = a; } - - // When a pre- or post-hook returns the result of this function, the value - // passed will be used in place of the original function's return value. Any - // post-hook override value will take precedence over a pre-hook override - // value. - exports.override = function(value) { - return new HookerOverride(value); - }; - - // When a pre-hook returns the result of this function, the value passed will - // be used in place of the original function's return value, and the original - // function will NOT be executed. - exports.preempt = function(value) { - return new HookerPreempt(value); - }; - - // When a pre-hook returns the result of this function, the context and - // arguments passed will be applied into the original function. - exports.filter = function(context, args) { - return new HookerFilter(context, args); - }; - - // Execute callback(s) for properties of the specified object. - function forMethods(obj, props, callback) { - var prop; - if (typeof props === "string") { - // A single prop string was passed. Create an array. - props = [props]; - } else if (props == null) { - // No props were passed, so iterate over all properties, building an - // array. Unfortunately, Object.keys(obj) doesn't work everywhere yet, so - // this has to be done manually. - props = []; - for (prop in obj) { - if (obj.hasOwnProperty(prop)) { - props.push(prop); - } - } - } - // Execute callback for every method in the props array. - var i = props.length; - while (i--) { - // If the property isn't a function... - if (toString.call(obj[props[i]]) !== "[object Function]" || - // ...or the callback returns false... - callback(obj, props[i]) === false) { - // ...remove it from the props array to be returned. - props.splice(i, 1); - } - } - // Return an array of method names for which the callback didn't fail. - return props; - } - - // Monkey-patch (hook) a method of an object. - exports.hook = function(obj, props, options) { - // If the props argument was omitted, shuffle the arguments. - if (options == null) { - options = props; - props = null; - } - // If just a function is passed instead of an options hash, use that as a - // pre-hook function. - if (typeof options === "function") { - options = {pre: options}; - } - - // Hook the specified method of the object. - return forMethods(obj, props, function(obj, prop) { - // The original (current) method. - var orig = obj[prop]; - // The new hooked function. - function hooked() { - var result, origResult, tmp; - - // Get an array of arguments. - var args = slice.call(arguments); - - // If passName option is specified, prepend prop to the args array, - // passing it as the first argument to any specified hook functions. - if (options.passName) { - args.unshift(prop); - } - - // If a pre-hook function was specified, invoke it in the current - // context with the passed-in arguments, and store its result. - if (options.pre) { - result = options.pre.apply(this, args); - } - - if (result instanceof HookerFilter) { - // If the pre-hook returned hooker.filter(context, args), invoke the - // original function with that context and arguments, and store its - // result. - origResult = result = orig.apply(result.context, result.args); - } else if (result instanceof HookerPreempt) { - // If the pre-hook returned hooker.preempt(value) just use the passed - // value and don't execute the original function. - origResult = result = result.value; - } else { - // Invoke the original function in the current context with the - // passed-in arguments, and store its result. - origResult = orig.apply(this, arguments); - // If the pre-hook returned hooker.override(value), use the passed - // value, otherwise use the original function's result. - result = result instanceof HookerOverride ? result.value : origResult; - } - - if (options.post) { - // If a post-hook function was specified, invoke it in the current - // context, passing in the result of the original function as the - // first argument, followed by any passed-in arguments. - tmp = options.post.apply(this, [origResult].concat(args)); - if (tmp instanceof HookerOverride) { - // If the post-hook returned hooker.override(value), use the passed - // value, otherwise use the previously computed result. - result = tmp.value; - } - } - - // Unhook if the "once" option was specified. - if (options.once) { - exports.unhook(obj, prop); - } - - // Return the result! - return result; - } - // Re-define the method. - obj[prop] = hooked; - // Fail if the function couldn't be hooked. - if (obj[prop] !== hooked) { return false; } - // Store a reference to the original method as a property on the new one. - obj[prop]._orig = orig; - }); - }; - - // Get a reference to the original method from a hooked function. - exports.orig = function(obj, prop) { - return obj[prop]._orig; - }; - - // Un-monkey-patch (unhook) a method of an object. - exports.unhook = function(obj, props) { - return forMethods(obj, props, function(obj, prop) { - // Get a reference to the original method, if it exists. - var orig = exports.orig(obj, prop); - // If there's no original method, it can't be unhooked, so fail. - if (!orig) { return false; } - // Unhook the method. - obj[prop] = orig; - }); - }; -}(typeof exports === "object" && exports || this)); diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/package.json b/spec/fixture/node_modules/grunt/node_modules/hooker/package.json deleted file mode 100644 index 2b3fcd9c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "hooker", - "description": "Monkey-patch (hook) functions for debugging and stuff.", - "version": "0.2.3", - "homepage": "http://github.com/cowboy/javascript-hooker", - "author": { - "name": "\"Cowboy\" Ben Alman", - "url": "http://benalman.com/" - }, - "repository": { - "type": "git", - "url": "git://github.com/cowboy/javascript-hooker.git" - }, - "bugs": { - "url": "https://github.com/cowboy/javascript-hooker/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/cowboy/javascript-hooker/blob/master/LICENSE-MIT" - } - ], - "dependencies": {}, - "devDependencies": { - "grunt": "~0.2.1" - }, - "keywords": [ - "patch", - "hook", - "function", - "debug", - "aop" - ], - "engines": { - "node": "*" - }, - "main": "lib/hooker", - "scripts": { - "test": "grunt test" - }, - "_npmUser": { - "name": "cowboy", - "email": "cowboy@rj3.net" - }, - "_id": "hooker@0.2.3", - "optionalDependencies": {}, - "_engineSupported": true, - "_npmVersion": "1.1.0-2", - "_nodeVersion": "v0.6.8", - "_defaultsLoaded": true, - "dist": { - "shasum": "b834f723cc4a242aa65963459df6d984c5d3d959", - "tarball": "http://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz" - }, - "maintainers": [ - { - "name": "cowboy", - "email": "cowboy@rj3.net" - } - ], - "directories": {}, - "_shasum": "b834f723cc4a242aa65963459df6d984c5d3d959", - "_from": "hooker@~0.2.3", - "_resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/parent.js b/spec/fixture/node_modules/grunt/node_modules/hooker/parent.js deleted file mode 100644 index c4a055e6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/parent.js +++ /dev/null @@ -1,17 +0,0 @@ -var spawn = require('child_process').spawn; - -function loop() { - console.log('starting'); - console.log(this); - //var child = spawn('./node_modules/nodeunit/bin/nodeunit', ['test']); - var child = spawn('node', ['child.js']); - child.stdout.on('data', function(buffer) { - process.stdout.write(buffer); - }); - child.on('exit', this.async()); -} - -var context = { - async: function() { return loop.bind(context); } -}; -loop.call(context); \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/hooker/test/hooker_test.js b/spec/fixture/node_modules/grunt/node_modules/hooker/test/hooker_test.js deleted file mode 100644 index dc5910a4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/hooker/test/hooker_test.js +++ /dev/null @@ -1,435 +0,0 @@ -/*global require:true */ -var hooker = require('../lib/hooker'); - -exports['hook'] = { - setUp: function(done) { - this.order = []; - this.track = function() { - [].push.apply(this.order, arguments); - }; - - this.prop = 1; - this.add = function(a, b) { - this.track("add", this.prop, a, b); - return this.prop + a + b; - }; - - this.obj = { - that: this, - prop: 1, - add1: function(a, b) { - this.that.track("add1", this.prop, a, b); - return this.prop + a + b; - }, - add2: function(a, b) { - this.that.track("add2", this.prop, a, b); - return this.prop + a + b; - }, - add3: function(a, b) { - this.that.track("add3", this.prop, a, b); - return this.prop + a + b; - } - }; - - done(); - }, - 'orig': function(test) { - test.expect(1); - var orig = this.add; - hooker.hook(this, "add", function() {}); - test.strictEqual(hooker.orig(this, "add"), orig, "should return a refernce to the original function."); - test.done(); - }, - 'once': function(test) { - test.expect(5); - var orig = this.add; - hooker.hook(this, "add", { - once: true, - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - } - }); - test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); - test.strictEqual(this.add, orig, "should automatically unhook when once is specified."); - this.order = []; - test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["add", 1, 2, 3], "only the original function should execute."); - test.done(); - }, - 'pre-hook (simple syntax)': function(test) { - test.expect(3); - // Pre-hook. - var result = hooker.hook(this, "add", function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - }); - test.deepEqual(result, ["add"], "add should have been hooked."); - test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); - test.done(); - }, - 'pre-hook': function(test) { - test.expect(3); - // Pre-hook. - var result = hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - } - }); - test.deepEqual(result, ["add"], "add should have been hooked."); - test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); - test.done(); - }, - 'post-hook': function(test) { - test.expect(3); - // Post-hook. - var result = hooker.hook(this, "add", { - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - } - }); - test.deepEqual(result, ["add"], "add should have been hooked."); - test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook': function(test) { - test.expect(2); - // Pre- & post-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - } - }); - test.strictEqual(this.add(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - test.done(); - }, - - 'pre-hook, return value override': function(test) { - test.expect(2); - // Pre-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // This return value will override the original function's return value. - return hooker.override("b" + this.prop + a + b); - } - }); - test.strictEqual(this.add(2, 3), "b123", "should return the overridden result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3], "functions should execute in-order."); - test.done(); - }, - 'post-hook, return value override': function(test) { - test.expect(2); - // Post-hook. - hooker.hook(this, "add", { - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - // This return value will override the original function's return value. - return hooker.override("a" + this.prop + a + b + result); - } - }); - test.strictEqual(this.add(2, 3), "a1236", "should return the post-hook overridden result."); - test.deepEqual(this.order, ["add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, return value override': function(test) { - test.expect(2); - // Pre- & post-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // This return value will override the original function's return value. - return hooker.override("b" + this.prop + a + b); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - // This return value will override the original function's return value - // AND the pre-hook's return value. - return hooker.override("a" + this.prop + a + b + result); - } - }); - test.strictEqual(this.add(2, 3), "a1236", "should return the overridden result, and post-hook result should take precedence over pre-hook result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - test.done(); - }, - - 'pre-hook, filtering arguments': function(test) { - test.expect(2); - // Pre-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Return hooker.filter(context, arguments) and they will be passed into - // the original function. The "track" and "order" propterites are just - // set here for the same of this unit test. - return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]); - } - }); - test.strictEqual(this.add(2, 3), "xyz", "should return the original function's result, given filtered context and arguments."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z"], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, filtering arguments': function(test) { - test.expect(2); - // Pre- & post-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Return hooker.filter(context, arguments) and they will be passed into - // the original function. The "track" and "order" propterites are just - // set here for the same of this unit test. - return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - } - }); - test.strictEqual(this.add(2, 3), "xyz", "should return the original function's result, given filtered context and arguments."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z", "after", 1, 2, 3, "xyz"], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, filtering arguments, return value override': function(test) { - test.expect(2); - // Pre- & post-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Return hooker.filter(context, arguments) and they will be passed into - // the original function. The "track" and "order" propterites are just - // set here for the same of this unit test. - return hooker.filter({prop: "x", track: this.track, order: this.order}, ["y", "z"]); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - // This return value will override the original function's return value - // AND the pre-hook's return value. - return hooker.override("a" + this.prop + a + b + result); - } - }); - test.strictEqual(this.add(2, 3), "a123xyz", "should return the post-hook overridden result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add", "x", "y", "z", "after", 1, 2, 3, "xyz"], "functions should execute in-order."); - test.done(); - }, - - 'pre-hook, preempt original function': function(test) { - test.expect(2); - // Pre-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Returning hooker.preempt will prevent the original function from being - // invoked and optionally set a return value. - return hooker.preempt(); - } - }); - test.strictEqual(this.add(2, 3), undefined, "should return the value passed to preempt."); - test.deepEqual(this.order, ["before", 1, 2, 3], "functions should execute in-order."); - test.done(); - }, - 'pre-hook, preempt original function with value': function(test) { - test.expect(2); - // Pre-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Returning hooker.preempt will prevent the original function from being - // invoked and optionally set a return value. - return hooker.preempt(9000); - } - }); - test.strictEqual(this.add(2, 3), 9000, "should return the value passed to preempt."); - test.deepEqual(this.order, ["before", 1, 2, 3], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, preempt original function with value': function(test) { - test.expect(2); - // Pre- & post-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Returning hooker.preempt will prevent the original function from being - // invoked and optionally set a return value. - return hooker.preempt(9000); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - } - }); - test.strictEqual(this.add(2, 3), 9000, "should return the value passed to preempt."); - test.deepEqual(this.order, ["before", 1, 2, 3, "after", 1, 2, 3, 9000], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, preempt original function with value, return value override': function(test) { - test.expect(2); - // Pre- & post-hook. - hooker.hook(this, "add", { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.track("before", this.prop, a, b); - // Returning hooker.preempt will prevent the original function from being - // invoked and optionally set a return value. - return hooker.preempt(9000); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.track("after", this.prop, a, b, result); - // This return value will override any preempt value set in pre-hook. - return hooker.override("a" + this.prop + a + b + result); - } - }); - test.strictEqual(this.add(2, 3), "a1239000", "should return the overridden result, and post-hook result should take precedence over preempt value."); - test.deepEqual(this.order, ["before", 1, 2, 3, "after", 1, 2, 3, 9000], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, some properties': function(test) { - test.expect(7); - // Pre- & post-hook. - var result = hooker.hook(this.obj, ["add1", "add2"], { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.that.track("before", this.prop, a, b); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.that.track("after", this.prop, a, b, result); - } - }); - test.deepEqual(result.sort(), ["add1", "add2"], "both functions should have been hooked."); - test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add1", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - this.order = []; - test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add2", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - this.order = []; - test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["add3", 1, 2, 3], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, all properties': function(test) { - test.expect(7); - // Pre- & post-hook. - var result = hooker.hook(this.obj, { - pre: function(a, b) { - // Arguments are passed into pre-hook as specified. - this.that.track("before", this.prop, a, b); - }, - post: function(result, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.that.track("after", this.prop, a, b, result); - } - }); - test.deepEqual(result.sort(), ["add1", "add2", "add3"], "all functions should have been hooked."); - test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add1", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - this.order = []; - test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add2", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - this.order = []; - test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, 2, 3, "add3", 1, 2, 3, "after", 1, 2, 3, 6], "functions should execute in-order."); - test.done(); - }, - 'pre- & post-hook, all properties, passName': function(test) { - test.expect(6); - // Pre- & post-hook. - hooker.hook(this.obj, { - passName: true, - pre: function(name, a, b) { - // Arguments are passed into pre-hook as specified. - this.that.track("before", this.prop, name, a, b); - }, - post: function(result, name, a, b) { - // Arguments to post-hook are the original function's return value, - // followed by the specified function arguments. - this.that.track("after", this.prop, name, a, b, result); - } - }); - test.strictEqual(this.obj.add1(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, "add1", 2, 3, "add1", 1, 2, 3, "after", 1, "add1", 2, 3, 6], "functions should execute in-order."); - this.order = []; - test.strictEqual(this.obj.add2(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, "add2", 2, 3, "add2", 1, 2, 3, "after", 1, "add2", 2, 3, 6], "functions should execute in-order."); - this.order = []; - test.strictEqual(this.obj.add3(2, 3), 6, "should return the original function's result."); - test.deepEqual(this.order, ["before", 1, "add3", 2, 3, "add3", 1, 2, 3, "after", 1, "add3", 2, 3, 6], "functions should execute in-order."); - test.done(); - }, - 'unhook one property': function(test) { - test.expect(5); - var orig = this.add; - hooker.hook(this, "add", function() {}); - var result = hooker.unhook(this, "add"); - test.deepEqual(result, ["add"], "one function should have been unhooked."); - test.strictEqual(this.add, orig, "should have unhooked, restoring the original function"); - result = hooker.unhook(this, "add"); - test.deepEqual(result, [], "nothing should have been unhooked."); - test.strictEqual(this.add, orig, "shouldn't explode if already unhooked"); - test.strictEqual(this.add.orig, undefined, "original function shouldn't have an orig property"); - test.done(); - }, - 'unhook some properties': function(test) { - test.expect(6); - var add1 = this.obj.add1; - var add2 = this.obj.add2; - hooker.hook(this.obj, ["add1", "add2"], function() {}); - test.strictEqual(hooker.orig(this.obj, "add1"), add1, "should return a refernce to the original function"); - test.strictEqual(hooker.orig(this.obj, "add2"), add2, "should return a refernce to the original function"); - test.strictEqual(hooker.orig(this.obj, "add3"), undefined, "should not have been hooked, so should not have an original function"); - var result = hooker.unhook(this.obj, ["add1", "add2"]); - test.deepEqual(result.sort(), ["add1", "add2"], "both functions should have been unhooked."); - test.strictEqual(this.obj.add1, add1, "should have unhooked, restoring the original function"); - test.strictEqual(this.obj.add2, add2, "should have unhooked, restoring the original function"); - test.done(); - }, - 'unhook all properties': function(test) { - test.expect(7); - var add1 = this.obj.add1; - var add2 = this.obj.add2; - var add3 = this.obj.add3; - hooker.hook(this.obj, function() {}); - test.strictEqual(hooker.orig(this.obj, "add1"), add1, "should return a refernce to the original function"); - test.strictEqual(hooker.orig(this.obj, "add2"), add2, "should return a refernce to the original function"); - test.strictEqual(hooker.orig(this.obj, "add3"), add3, "should return a refernce to the original function"); - var result = hooker.unhook(this.obj); - test.deepEqual(result.sort(), ["add1", "add2", "add3"], "all functions should have been unhooked."); - test.strictEqual(this.obj.add1, add1, "should have unhooked, restoring the original function"); - test.strictEqual(this.obj.add2, add2, "should have unhooked, restoring the original function"); - test.strictEqual(this.obj.add3, add3, "should have unhooked, restoring the original function"); - test.done(); - } -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/.npmignore b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/.npmignore deleted file mode 100644 index fe46877a..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -*~ -*sublime-* diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/.travis.yml deleted file mode 100644 index 0bab9cd8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ - language: node_js - node_js: - - 0.4 - - 0.6 - - 0.8 diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/LICENSE b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/LICENSE deleted file mode 100644 index d518d837..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2011 Alexander Shtuchkin - -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/spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md deleted file mode 100644 index ba30a32c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md +++ /dev/null @@ -1,72 +0,0 @@ -iconv-lite - pure javascript character encoding conversion -====================================================================== - -[![Build Status](https://secure.travis-ci.org/ashtuchkin/iconv-lite.png?branch=master)](http://travis-ci.org/ashtuchkin/iconv-lite) - -## Features - -* Pure javascript. Doesn't need native code compilation. -* Easy API. -* Works on Windows and in sandboxed environments like [Cloud9](http://c9.io). -* Encoding is much faster than node-iconv (see below for performance comparison). - -## Usage - - var iconv = require('iconv-lite'); - - // Convert from an encoded buffer to string. - str = iconv.decode(buf, 'win1251'); - - // Convert from string to an encoded buffer. - buf = iconv.encode("Sample input string", 'win1251'); - - // Check if encoding is supported - iconv.encodingExists("us-ascii") - - -## Supported encodings - -* All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64' -* All widespread single byte encodings: Windows 125x family, ISO-8859 family, - IBM/DOS codepages, Macintosh family, KOI8 family. - Aliases like 'latin1', 'us-ascii' also supported. -* Multibyte encodings: 'gbk', 'gb2313', 'Big5', 'cp950'. - -Others are easy to add, see the source. Please, participate. -Most encodings are generated from node-iconv. Thank you Ben Noordhuis and iconv authors! - -Not supported yet: EUC family, Shift_JIS. - - -## Encoding/decoding speed - -Comparison with node-iconv module (1000x256kb, on Ubuntu 12.04, Core i5/2.5 GHz, Node v0.8.7). -Note: your results may vary, so please always check on your hardware. - - operation iconv@1.2.4 iconv-lite@0.2.4 - ---------------------------------------------------------- - encode('win1251') ~115 Mb/s ~230 Mb/s - decode('win1251') ~95 Mb/s ~130 Mb/s - - -## Notes - -When decoding, a 'binary'-encoded string can be used as a source buffer. -Untranslatable characters are set to � or ?. No transliteration is currently supported, pull requests are welcome. - -## Testing - - git clone git@github.com:ashtuchkin/iconv-lite.git - cd iconv-lite - npm install - npm test - - # To view performance: - node test/performance.js - -## TODO - -* Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')). -* Add more encodings. -* Add transliteration (best fit char). -* Add tests and correct support of variable-byte encodings (currently work is delegated to node). diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md~ b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md~ deleted file mode 100644 index 5f575615..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/README.md~ +++ /dev/null @@ -1,54 +0,0 @@ -iconv-lite - native javascript conversion between character encodings. -====================================================================== - -## Usage - - var iconv = require('iconv-lite'); - - // Convert from an encoded buffer to string. - str = iconv.fromEncoding(buf, 'win-1251'); - // Or - str = iconv.decode(buf, 'win-1251'); - - // Convert from string to an encoded buffer. - buf = iconv.toEncoding("Sample input string", 'win-1251'); - // Or - buf = iconv.encode("Sample input string", 'win-1251'); - -## Supported encodings - -Currently only a small part of encodings supported: - -* All node.js native encodings: 'utf8', 'ucs2', 'ascii', 'binary', 'base64'. -* 'latin1' -* Cyrillic encodings: 'windows-1251', 'koi8-r', 'iso 8859-5'. - -Other encodings are easy to add, see the source. Please, participate. - - -## Encoding/decoding speed - -Comparison with iconv module (1000 times 256kb, on Core i5/2.5 GHz). - - Operation\module iconv iconv-lite (this) - toEncoding('win1251') 19.57 mb/s 49.04 mb/s - fromEncoding('win1251') 16.39 mb/s 24.11 mb/s - - -## Notes - -This module is JavaScript-only, thus can be used in a sandboxed environment like [Cloud9](http://c9.io). - -Untranslatable characters are set to '?'. No transliteration is currently supported, pull requests are welcome. - -## Testing - - npm install --dev iconv-lite - vows - -## TODO - -* Support streaming character conversion, something like util.pipe(req, iconv.fromEncodingStream('latin1')). -* Add more encodings. -* Add transliteration (best fit char). -* Add tests and correct support of variable-byte encodings (currently work is delegated to node). diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/big5.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/big5.js deleted file mode 100644 index 0423d63a..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/big5.js +++ /dev/null @@ -1,9 +0,0 @@ -var big5Table = require('./table/big5.js'); -module.exports = { - 'windows950': 'big5', - 'cp950': 'big5', - 'big5': { - type: 'table', - table: big5Table - } -} diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/gbk.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/gbk.js deleted file mode 100644 index 78a63ec5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/gbk.js +++ /dev/null @@ -1,9 +0,0 @@ -var gbkTable = require('./table/gbk.js'); -module.exports = { - 'windows936': 'gbk', - 'gb2312': 'gbk', - 'gbk': { - type: 'table', - table: gbkTable - } -} diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/singlebyte.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/singlebyte.js deleted file mode 100644 index f41a7ea7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/singlebyte.js +++ /dev/null @@ -1,340 +0,0 @@ -module.exports = { - "437": "cp437", - "737": "cp737", - "775": "cp775", - "850": "cp850", - "852": "cp852", - "855": "cp855", - "857": "cp857", - "858": "cp858", - "860": "cp860", - "861": "cp861", - "862": "cp862", - "863": "cp863", - "864": "cp864", - "865": "cp865", - "866": "cp866", - "869": "cp869", - "874": "iso885911", - "1250": "windows1250", - "1251": "windows1251", - "1252": "windows1252", - "1253": "windows1253", - "1254": "windows1254", - "1255": "windows1255", - "1256": "windows1256", - "1257": "windows1257", - "1258": "windows1258", - "10000": "macroman", - "10006": "macgreek", - "10007": "maccyrillic", - "10029": "maccenteuro", - "10079": "maciceland", - "10081": "macturkish", - "20866": "koi8r", - "21866": "koi8u", - "28591": "iso88591", - "28592": "iso88592", - "28593": "iso88593", - "28594": "iso88594", - "28595": "iso88595", - "28596": "iso88596", - "28597": "iso88597", - "28598": "iso88598", - "28599": "iso88599", - "28600": "iso885910", - "28601": "iso885911", - "28603": "iso885913", - "28604": "iso885914", - "28605": "iso885915", - "28606": "iso885916", - "ascii8bit": "ascii", - "usascii": "ascii", - "latin1": "iso88591", - "latin2": "iso88592", - "latin3": "iso88593", - "latin4": "iso88594", - "latin6": "iso885910", - "latin7": "iso885913", - "latin8": "iso885914", - "latin9": "iso885915", - "latin10": "iso885916", - "cp819": "iso88951", - "arabic": "iso88596", - "arabic8": "iso88596", - "greek": "iso88597", - "greek8": "iso88597", - "hebrew": "iso88598", - "hebrew8": "iso88598", - "turkish": "iso88599", - "turkish8": "iso88599", - "thai": "iso885911", - "thai8": "iso885911", - "tis620": "iso885911", - "windows874": "iso885911", - "win874": "iso885911", - "cp874": "iso885911", - "celtic": "iso885914", - "celtic8": "iso885914", - "cp20866": "koi8r", - "ibm878": "koi8r", - "cp21866": "koi8u", - "ibm1168": "koi8u", - "windows1250": { - "type": "singlebyte", - "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“â€â€¢â€“—�™š›śťžź ˇ˘Å¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»ĽËľżŔÃÂĂÄĹĆÇČÉĘËĚÃÃŽÄŽÄŃŇÓÔÅÖ×ŘŮÚŰÜÃŢßŕáâăäĺćçÄéęëěíîÄđńňóôőö÷řůúűüýţ˙" - }, - "win1250": "windows1250", - "cp1250": "windows1250", - "windows1251": { - "type": "singlebyte", - "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋÐђ‘’“â€â€¢â€“—�™љ›њќћџ ЎўЈ¤Ò¦§Ð©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑ" - }, - "win1251": "windows1251", - "cp1251": "windows1251", - "windows1252": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“â€â€¢â€“—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "win1252": "windows1252", - "cp1252": "windows1252", - "windows1253": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“â€â€¢â€“—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎÎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏώ�" - }, - "win1253": "windows1253", - "cp1253": "windows1253", - "windows1254": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“â€â€¢â€“—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "win1254": "windows1254", - "cp1254": "windows1254", - "windows1255": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“â€â€¢â€“—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹ�ֻּֽ־ֿ׀×ׂ׃װױײ׳״�������×בגדהוזחטיךכל×מןנסעףפץצקרשת��‎â€ï¿½" - }, - "win1255": "windows1255", - "cp1255": "windows1255", - "windows1256": { - "type": "singlebyte", - "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“â€â€¢â€“—ک™ڑ›œ‌â€ÚºÂ ØŒÂ¢Â£Â¤Â¥Â¦Â§Â¨Â©Ú¾Â«Â¬Â­Â®Â¯Â°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Ø›Â»Â¼Â½Â¾ØŸÛءآأؤإئابةتثجحخدذرزسشصض×طظعغـÙقكàلâمنهوçèéêëىيîïًٌÙَôÙÙ÷ّùْûü‎â€Û’" - }, - "win1256": "windows1256", - "cp1256": "windows1256", - "windows1257": { - "type": "singlebyte", - "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“â€â€¢â€“—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲÅŚŪÜŻŽßąįÄćäåęēÄéźėģķīļšńņóÅõö÷ųłśūüżž˙" - }, - "win1257": "windows1257", - "cp1257": "windows1257", - "windows1258": { - "type": "singlebyte", - "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“â€â€¢â€“—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂĂÄÅÆÇÈÉÊË̀ÃÃŽÃÄÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêëÌíîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "win1258": "windows1258", - "cp1258": "windows1258", - "iso88591": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28591": "iso88591", - "iso88592": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ Ą˘Å¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťźËžżŔÃÂĂÄĹĆÇČÉĘËĚÃÃŽÄŽÄŃŇÓÔÅÖ×ŘŮÚŰÜÃŢßŕáâăäĺćçÄéęëěíîÄđńňóôőö÷řůúűüýţ˙" - }, - "cp28592": "iso88592", - "iso88593": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�ݰħ²³´µĥ·¸ışğĵ½�żÀÃÂ�ÄĊĈÇÈÉÊËÌÃÃŽÃ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ÄùúûüŭÅË™" - }, - "cp28593": "iso88593", - "iso88594": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ĄĸŖ¤Ĩϧ¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩšēģŧŊžŋĀÃÂÃÄÅÆĮČÉĘËĖÃÎĪÄŅŌĶÔÕÖרŲÚÛÜŨŪßÄáâãäåæįÄéęëėíîīđņÅķôõö÷øųúûüũū˙" - }, - "cp28594": "iso88594", - "iso88595": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ÐЂЃЄЅІЇЈЉЊЋЌ­ЎÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑ№ёђѓєѕіїјљњћќ§ўџ" - }, - "cp28595": "iso88595", - "iso88596": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـÙقكلمنهوىيًٌÙÙŽÙÙّْ�������������" - }, - "cp28596": "iso88596", - "iso88597": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎÎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπÏςστυφχψωϊϋόÏώ�" - }, - "cp28597": "iso88597", - "iso88598": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗×בגדהוזחטיךכל×מןנסעףפץצקרשת��‎â€ï¿½" - }, - "cp28598": "iso88598", - "iso88599": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "cp28599": "iso88599", - "iso885910": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ĄĒĢĪĨͧĻÄŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÃÂÃÄÅÆĮČÉĘËĖÃÃŽÃÃŅŌÓÔÕÖŨØŲÚÛÜÃÞßÄáâãäåæįÄéęëėíîïðņÅóôõöũøųúûüýþĸ" - }, - "cp28600": "iso885910", - "iso885911": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ à¸à¸‚ฃคฅฆงจฉชซฌà¸à¸Žà¸à¸à¸‘ฒณดตถทธนบปผà¸à¸žà¸Ÿà¸ à¸¡à¸¢à¸£à¸¤à¸¥à¸¦à¸§à¸¨à¸©à¸ªà¸«à¸¬à¸­à¸®à¸¯à¸°à¸±à¸²à¸³à¸´à¸µà¸¶à¸·à¸¸à¸¹à¸ºï¿½ï¿½ï¿½ï¿½à¸¿à¹€à¹à¹‚ใไๅๆ็่้๊๋์à¹à¹Žà¹à¹à¹‘๒๓๔๕๖๗๘๙๚๛����" - }, - "cp28601": "iso885911", - "iso885913": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ â€Â¢Â£Â¤â€žÂ¦Â§Ã˜Â©Å–«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲÅŚŪÜŻŽßąįÄćäåęēÄéźėģķīļšńņóÅõö÷ųłśūüżž’" - }, - "cp28603": "iso885913", - "iso885914": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀá¹Â¶á¹–áºá¹—ẃṠỳẄẅṡÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃŴÑÒÓÔÕÖṪØÙÚÛÜÃŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" - }, - "cp28604": "iso885914", - "iso885915": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28605": "iso885915", - "iso885916": { - "type": "singlebyte", - "chars": "€Â‚ƒ„…†‡ˆ‰Š‹ŒÂŽ‘’“”•–—˜™š›œÂžŸ ĄąÅ€„Чš©Ș«Ź­źŻ°±ČłŽâ€Â¶Â·Å¾Äș»ŒœŸżÀÃÂĂÄĆÆÇÈÉÊËÌÃÃŽÃÄŃÒÓÔÅÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" - }, - "cp28606": "iso885916", - "cp437": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿âŒÂ¬Â½Â¼Â¡Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm437": "cp437", - "cp737": { - "type": "singlebyte", - "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπÏσςτυφχψ░▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀ωάέήϊίόÏϋώΆΈΉΊΌΎÎ±≥≤ΪΫ÷≈°∙·√â¿Â²â– Â " - }, - "ibm737": "cp737", - "cp775": { - "type": "singlebyte", - "chars": "ĆüéÄäģåćłēŖŗīŹÄÅÉæÆÅöĢ¢ŚśÖÜø£Ø×¤ĀĪóŻżźâ€Â¦Â©Â®Â¬Â½Â¼Å«»░▒▓│┤ĄČĘĖ╣║╗â•ĮŠâ”└┴┬├─┼ŲŪ╚╔╩╦╠â•╬ŽąÄęėįšųūž┘┌█▄▌â–▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " - }, - "ibm775": "cp775", - "cp850": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÃÂÀ©╣║╗â•¢¥â”└┴┬├─┼ãÃ╚╔╩╦╠â•╬¤ðÃÊËÈıÃÃŽÃ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýï´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm850": "cp850", - "cp852": { - "type": "singlebyte", - "chars": "ÇüéâäůćçłëÅőîŹÄĆÉĹĺôöĽľŚśÖÜŤťÅ×ÄáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÃÂĚŞ╣║╗╯żâ”└┴┬├─┼Ăă╚╔╩╦╠â•╬¤đÄĎËÄŇÃÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÃţ´­Ë˛ˇ˘§÷¸°¨˙űŘř■ " - }, - "ibm852": "cp852", - "cp855": { - "type": "singlebyte", - "chars": "ђЂѓЃёÐєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџÐюЮъЪаÐбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗â•йЙâ”└┴┬├─┼кК╚╔╩╦╠â•╬¤лЛмМнÐоОп┘┌█▄ПÑ▀ЯрРÑСтТуУжЖвВьЬ№­ыЫзЗшШÑЭщЩчЧ§■ " - }, - "ibm855": "cp855", - "cp857": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÃÂÀ©╣║╗â•¢¥â”└┴┬├─┼ãÃ╚╔╩╦╠â•╬¤ºªÊËÈ�ÃÃŽÃ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " - }, - "ibm857": "cp857", - "cp858": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÃÂÀ©╣║╗â•¢¥â”└┴┬├─┼ãÃ╚╔╩╦╠â•╬¤ðÃÊËÈ€ÃÃŽÃ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýï´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm858": "cp858", - "cp860": { - "type": "singlebyte", - "chars": "ÇüéâãàÃçêÊèÃÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm860": "cp860", - "cp861": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèÃðÞÄÅÉæÆôöþûÃýÖÜø£Ø₧ƒáíóúÃÃÓÚ¿âŒÂ¬Â½Â¼Â¡Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm861": "cp861", - "cp862": { - "type": "singlebyte", - "chars": "×בגדהוזחטיךכל×מןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿âŒÂ¬Â½Â¼Â¡Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm862": "cp862", - "cp863": { - "type": "singlebyte", - "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÃûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯ÎâŒÂ¬Â½Â¼Â¾Â«Â»â–‘▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm863": "cp863", - "cp864": { - "type": "singlebyte", - "chars": "°·∙√▒─│┼┤┬├┴â”┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎïºïº•ﺙ،ïºïº¡ïº¥Ù Ù¡Ù¢Ù£Ù¤Ù¥Ù¦Ù§Ù¨Ù©ï»‘؛ﺱﺵﺹ؟¢ﺀïºïºƒïº…ﻊﺋïºïº‘ﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿï»ï»…ﻋï»Â¦Â¬Ã·Ã—ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎï»ï»¡ï¹½Ù‘ﻥﻩﻬﻰﻲï»ï»•ﻵﻶï»ï»™ï»±â– ï¿½" - }, - "ibm864": "cp864", - "cp865": { - "type": "singlebyte", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿âŒÂ¬Â½Â¼Â¡Â«Â¤â–‘▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â¿Â²â– Â " - }, - "ibm865": "cp865", - "cp866": { - "type": "singlebyte", - "chars": "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗â•╜╛â”└┴┬├─┼╞╟╚╔╩╦╠â•╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–▀рÑтуфхцчшщъыьÑÑŽÑÐёЄєЇїЎў°∙·√№¤■ " - }, - "ibm866": "cp866", - "cp869": { - "type": "singlebyte", - "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Î²³ά£έήίϊÎÏŒÏΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜÎ╣║╗â•ΞΟâ”└┴┬├─┼ΠΡ╚╔╩╦╠â•╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπÏσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " - }, - "ibm869": "cp869", - "maccenteuro": { - "type": "singlebyte", - "chars": "ÄĀÄÉĄÖÜáąČäÄĆć鏟ĎíÄĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňÅÕőŌ–—“â€â€˜â€™Ã·â—ŠÅŔŕŘ‹›řŖŗŠ‚„šŚśÃŤťÃŽžŪÓÔūŮÚůŰűŲųÃýķŻÅżĢˇ" - }, - "maccroatian": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑âˆÅ¡âˆ«ÂªÂºâ„¦Å¾Ã¸Â¿Â¡Â¬âˆšÆ’≈ƫȅ ÀÃÕŒœÄ—“â€â€˜â€™Ã·â—Šï¿½Â©â„¤‹›Æ»–·‚„‰ÂćÃÄÈÃÃŽÃÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" - }, - "maccyrillic": { - "type": "singlebyte", - "chars": "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“â€â€˜â€™Ã·â€žÐŽÑžÐÑŸâ„–ÐÑ‘ÑабвгдежзийклмнопрÑтуфхцчшщъыьÑю¤" - }, - "macgreek": { - "type": "singlebyte", - "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάάΟΡ≈Τ«»… ΥΧΆΈœ–―“â€â€˜â€™Ã·Î‰ÎŠÎŒÎŽÎ­Î®Î¯ÏŒÎÏαβψδεφγηιξκλμνοπώÏστθωςχυζϊϋÎΰ�" - }, - "maciceland": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü𢣧•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦Ã¦Ã¸Â¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸â„¤ÃðÞþý·‚„‰ÂÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macroman": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦Ã¦Ã¸Â¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸â„¤‹›ï¬ï¬‚‡·‚„‰ÂÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macromania": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦ÄƒÅŸÂ¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸â„¤‹›Ţţ‡·‚„‰ÂÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macthai": { - "type": "singlebyte", - "chars": "«»…ï¢ï¢’“â€ï¢™ï¿½â€¢ï¢„ï¢ï¢ï¢“‘’� à¸à¸‚ฃคฅฆงจฉชซฌà¸à¸Žà¸à¸à¸‘ฒณดตถทธนบปผà¸à¸žà¸Ÿà¸ à¸¡à¸¢à¸£à¸¤à¸¥à¸¦à¸§à¸¨à¸©à¸ªà¸«à¸¬à¸­à¸®à¸¯à¸°à¸±à¸²à¸³à¸´à¸µà¸¶à¸·à¸¸à¸¹à¸ºï»¿â€‹â€“—฿เà¹à¹‚ใไๅๆ็่้๊๋์à¹â„¢à¹à¹à¹‘๒๓๔๕๖๗๘๙®©����" - }, - "macturkish": { - "type": "singlebyte", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑âˆÏ€âˆ«ÂªÂºâ„¦Ã¦Ã¸Â¿Â¡Â¬âˆšÆ’≈∆«»… ÀÃÕŒœ–—“â€â€˜â€™Ã·â—ŠÃ¿Å¸ÄžÄŸÄ°Ä±ÅžÅŸâ€¡Â·â€šâ€žâ€°Ã‚ÊÃËÈÃÃŽÃÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸Ë˛ˇ" - }, - "macukraine": { - "type": "singlebyte", - "chars": "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ò£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“â€â€˜â€™Ã·â€žÐŽÑžÐÑŸâ„–ÐÑ‘ÑабвгдежзийклмнопрÑтуфхцчшщъыьÑю¤" - }, - "koi8r": { - "type": "singlebyte", - "chars": "─│┌â”└┘├┤┬┴┼▀▄█▌â–░▒▓⌠■∙√≈≤≥ ⌡°²·÷â•║╒ё╓╔╕╖╗╘╙╚╛╜â•╞╟╠╡Ð╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопÑÑ€ÑтужвьызшÑщчъЮÐБЦДЕФГХИЙКЛМÐОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8u": { - "type": "singlebyte", - "chars": "─│┌â”└┘├┤┬┴┼▀▄█▌â–░▒▓⌠■∙√≈≤≥ ⌡°²·÷â•║╒ёє╔ії╗╘╙╚╛ґâ•╞╟╠╡ÐЄ╣ІЇ╦╧╨╩╪Ò╬©юабцдефгхийклмнопÑÑ€ÑтужвьызшÑщчъЮÐБЦДЕФГХИЙКЛМÐОПЯРСТУЖВЬЫЗШЭЩЧЪ" - } -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/big5.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/big5.js deleted file mode 100644 index 605c72d3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/big5.js +++ /dev/null @@ -1 +0,0 @@ -module.exports={"33088":19991,"33089":20002,"33090":20012,"33091":20053,"33092":20066,"33093":20106,"33094":20144,"33095":20203,"33096":20205,"33097":20220,"33098":20252,"33099":20362,"33100":20479,"33101":20546,"33102":20560,"33103":20600,"33104":20696,"33105":20702,"33106":20724,"33107":20758,"33108":20810,"33109":20817,"33110":20836,"33111":20842,"33112":20869,"33113":20880,"33114":20893,"33115":20902,"33116":20904,"33117":20905,"33118":20935,"33119":20950,"33120":20955,"33121":20972,"33122":20988,"33123":21003,"33124":21012,"33125":21013,"33126":21024,"33127":21035,"33128":21049,"33129":21071,"33130":21105,"33131":21136,"33132":21138,"33133":21140,"33134":21148,"33135":21167,"33136":21173,"33137":21200,"33138":21248,"33139":21255,"33140":21284,"33141":21318,"33142":21343,"33143":21395,"33144":21424,"33145":21469,"33146":21539,"33147":21584,"33148":21585,"33149":21642,"33150":21661,"33185":21667,"33186":21684,"33187":21712,"33188":21795,"33189":21823,"33190":21836,"33191":21843,"33192":21853,"33193":21868,"33194":21918,"33195":21929,"33196":21996,"33197":22005,"33198":22051,"33199":22096,"33200":22140,"33201":22154,"33202":22164,"33203":22176,"33204":22191,"33205":22232,"33206":22272,"33207":22361,"33208":22373,"33209":22399,"33210":22405,"33211":22409,"33212":22433,"33213":22444,"33214":22452,"33215":22464,"33216":22472,"33217":22483,"33218":22511,"33219":22596,"33220":22636,"33221":22674,"33222":22682,"33223":22706,"33224":22712,"33225":22757,"33226":22779,"33227":22786,"33228":22795,"33229":22800,"33230":22808,"33231":22811,"33232":29836,"33233":29837,"33234":29849,"33235":29851,"33236":29860,"33237":29876,"33238":29881,"33239":29896,"33240":29900,"33241":29904,"33242":29907,"33243":30018,"33244":30037,"33245":30062,"33246":30093,"33247":30110,"33248":30172,"33249":30252,"33250":30287,"33251":30289,"33252":30323,"33253":30324,"33254":30373,"33255":30425,"33256":30478,"33257":30479,"33258":30552,"33259":30578,"33260":30583,"33261":30584,"33262":30586,"33263":30587,"33264":30616,"33265":30639,"33266":30654,"33267":30659,"33268":30661,"33269":30667,"33270":30685,"33271":30694,"33272":30708,"33273":30750,"33274":30781,"33275":30786,"33276":30788,"33277":30795,"33278":30801,"33344":21782,"33345":22775,"33346":38964,"33347":33883,"33348":28948,"33349":33398,"33350":35158,"33351":40236,"33352":40206,"33353":36527,"33354":24674,"33355":26214,"33356":34510,"33357":25785,"33358":37772,"33359":22107,"33360":28485,"33361":35532,"33362":29001,"33363":24012,"33364":34633,"33365":39464,"33366":31658,"33367":36107,"33368":39255,"33369":23597,"33370":32331,"33371":38938,"33372":20518,"33373":25458,"33374":40568,"33375":30783,"33376":40633,"33377":40634,"33378":36046,"33379":35715,"33380":61305,"33381":33931,"33382":37284,"33383":31331,"33384":25776,"33385":24061,"33386":24214,"33387":32865,"33388":26965,"33389":31466,"33390":28710,"33391":26812,"33392":31095,"33393":28060,"33394":36841,"33395":31074,"33396":22178,"33397":34687,"33398":21093,"33399":31108,"33400":28300,"33401":37271,"33402":31622,"33403":38956,"33404":26717,"33405":20397,"33406":34222,"33441":31725,"33442":34635,"33443":20534,"33444":26893,"33445":27542,"33446":24910,"33447":20855,"33448":30495,"33449":20516,"33450":32622,"33451":30452,"33452":27097,"33453":24803,"33454":25334,"33455":21599,"33456":38788,"33457":22092,"33458":20677,"33459":22040,"33460":34398,"33461":22834,"33462":22875,"33463":22877,"33464":22883,"33465":22892,"33466":22939,"33467":22999,"33468":23019,"33469":23066,"33470":23210,"33471":23248,"33472":23281,"33473":23350,"33474":23497,"33475":23539,"33476":23571,"33477":23580,"33478":23582,"33479":23635,"33480":23705,"33481":23708,"33482":23738,"33483":23739,"33484":23745,"33485":23797,"33486":23802,"33487":23829,"33488":23832,"33489":23870,"33490":23891,"33491":23900,"33492":23917,"33493":23923,"33494":23924,"33495":23948,"33496":23952,"33497":23993,"33498":24016,"33499":24019,"33500":24135,"33501":24164,"33502":24271,"33503":24272,"33504":24298,"33505":24304,"33506":24329,"33507":24332,"33508":24337,"33509":24353,"33510":24372,"33511":24385,"33512":24389,"33513":24401,"33514":24412,"33515":24422,"33516":24451,"33517":24560,"33518":24650,"33519":24672,"33520":24715,"33521":24742,"33522":24798,"33523":24849,"33524":24864,"33525":24865,"33526":24892,"33527":24893,"33528":24984,"33529":25015,"33530":25076,"33531":25107,"33532":25117,"33533":25118,"33534":25143,"33600":24186,"33601":27664,"33602":21454,"33603":20267,"33604":20302,"33605":21556,"33606":22257,"33607":22766,"33608":22841,"33609":22918,"33610":23596,"33611":20915,"33612":20914,"33613":28798,"33614":35265,"33615":35282,"33616":36125,"33617":36710,"33618":20122,"33619":26469,"33620":20177,"33621":20004,"33622":21327,"33623":23626,"33624":20872,"33625":24213,"33626":25269,"33627":19996,"33628":20105,"33629":29366,"33630":31868,"33631":32416,"33632":21351,"33633":36711,"33634":37048,"33635":38271,"33636":38376,"33637":20384,"33638":20387,"33639":20822,"33640":21017,"33641":21170,"33642":21364,"33643":22850,"33644":24069,"33645":26594,"33646":27769,"33647":20026,"33648":32419,"33649":32418,"33650":32426,"33651":32427,"33652":32421,"33653":32422,"33654":32417,"33655":32989,"33656":33486,"33657":35745,"33658":35746,"33659":35747,"33660":36126,"33661":36127,"33662":20891,"33697":36712,"33698":38377,"33699":38886,"33700":39029,"33701":39118,"33702":39134,"33703":20457,"33704":20204,"33705":20261,"33706":20010,"33707":20262,"33708":20179,"33709":20923,"33710":21018,"33711":21093,"33712":21592,"33713":23089,"33714":23385,"33715":23777,"33716":23707,"33717":23704,"33718":24072,"33719":24211,"33720":24452,"33721":25375,"33722":26102,"33723":26187,"33724":20070,"33725":27902,"33726":27971,"33727":20044,"33728":29421,"33729":29384,"33730":20137,"33731":30757,"33732":31210,"33733":32442,"33734":32433,"33735":32441,"33736":32431,"33737":32445,"33738":32432,"33739":32423,"33740":32429,"33741":32435,"33742":32440,"33743":32439,"33744":32961,"33745":33033,"33746":21005,"33747":35760,"33748":35750,"33749":35752,"33750":35751,"33751":35754,"33752":35759,"33753":35757,"33754":35755,"33755":23682,"33756":36130,"33757":36129,"33758":36713,"33759":36715,"33760":38025,"33761":38024,"33762":38026,"33763":38027,"33764":38378,"33765":38453,"33766":38485,"33767":38473,"33768":39269,"33769":39532,"33770":39592,"33771":20266,"33772":20255,"33773":20390,"33774":20391,"33775":21153,"33776":21160,"33777":21306,"33778":21442,"33779":21713,"33780":38382,"33781":34900,"33782":22269,"33783":22362,"33784":22441,"33785":25191,"33786":22815,"33787":23044,"33788":22919,"33789":19987,"33790":23558,"33856":23625,"33857":23781,"33858":23703,"33859":24102,"33860":24080,"33861":24352,"33862":24378,"33863":20174,"33864":24469,"33865":20932,"33866":24581,"33867":25195,"33868":25346,"33869":25194,"33870":25249,"33871":25379,"33872":36133,"33873":21551,"33874":26011,"33875":26025,"33876":26172,"33877":21206,"33878":24323,"33879":26465,"33880":26541,"33881":26432,"33882":27682,"33883":20937,"33884":27973,"33885":28170,"33886":27882,"33887":27814,"33888":20928,"33889":29301,"33890":29424,"33891":29616,"33892":20135,"33893":27605,"33894":24322,"33895":20247,"33896":32458,"33897":32479,"33898":32461,"33899":32459,"33900":32460,"33901":32454,"33902":32453,"33903":32452,"33904":32456,"33905":32449,"33906":32450,"33907":38069,"33908":20064,"33909":33626,"33910":33550,"33911":33682,"33912":24196,"33913":33483,"33914":22788,"33915":26415,"33916":34926,"33917":35269,"33918":35268,"33953":35775,"33954":35766,"33955":35776,"33956":35767,"33957":35768,"33958":35774,"33959":35772,"33960":35769,"33961":36137,"33962":36131,"33963":36143,"33964":36135,"33965":36138,"33966":36139,"33967":36717,"33968":36719,"33969":36825,"33970":36830,"33971":36851,"33972":38039,"33973":38035,"33974":38031,"33975":38034,"33976":38381,"33977":38472,"33978":38470,"33979":38452,"33980":39030,"33981":39031,"33982":40060,"33983":40479,"33984":21348,"33985":40614,"33986":22791,"33987":20263,"33988":20254,"33989":20975,"33990":21056,"33991":21019,"33992":21171,"33993":21195,"33994":20007,"33995":21333,"33996":21727,"33997":21796,"33998":20052,"33999":22260,"34000":23591,"34001":22330,"34002":25253,"34003":22490,"34004":22774,"34005":23090,"34006":23547,"34007":23706,"34008":24103,"34009":24079,"34010":21397,"34011":21417,"34012":24694,"34013":38391,"34014":24812,"34015":24699,"34016":24700,"34017":25315,"34018":25381,"34019":25442,"34020":25196,"34021":26531,"34022":26635,"34023":26632,"34024":38054,"34025":27531,"34026":22771,"34027":27695,"34028":27689,"34029":28044,"34030":20945,"34031":28270,"34032":28065,"34033":27748,"34034":27979,"34035":27985,"34036":28067,"34037":26080,"34038":29369,"34039":33487,"34040":30011,"34041":30153,"34042":21457,"34043":30423,"34044":30746,"34045":31174,"34046":31383,"34112":31508,"34113":31499,"34114":32478,"34115":32467,"34116":32466,"34117":32477,"34118":19997,"34119":32476,"34120":32473,"34121":32474,"34122":32470,"34123":32475,"34124":32899,"34125":32958,"34126":32960,"34127":21326,"34128":33713,"34129":33484,"34130":34394,"34131":35270,"34132":35780,"34133":35789,"34134":35777,"34135":35778,"34136":35791,"34137":35781,"34138":35784,"34139":35787,"34140":35785,"34141":35786,"34142":35779,"34143":36142,"34144":36148,"34145":36144,"34146":36155,"34147":36146,"34148":36153,"34149":36154,"34150":36149,"34151":20080,"34152":36140,"34153":36152,"34154":36151,"34155":36722,"34156":36724,"34157":36726,"34158":36827,"34159":37038,"34160":20065,"34161":38046,"34162":38062,"34163":38041,"34164":38048,"34165":38055,"34166":38045,"34167":38052,"34168":38051,"34169":38389,"34170":38384,"34171":24320,"34172":38386,"34173":38388,"34174":38387,"34209":38431,"34210":38454,"34211":38451,"34212":38887,"34213":39033,"34214":39034,"34215":39035,"34216":39274,"34217":39277,"34218":39272,"34219":39278,"34220":39276,"34221":20911,"34222":39533,"34223":20081,"34224":20538,"34225":20256,"34226":20165,"34227":20542,"34228":20260,"34229":20588,"34230":38130,"34231":21183,"34232":31215,"34233":27719,"34234":21527,"34235":21596,"34236":21595,"34237":22253,"34238":22278,"34239":28034,"34240":22359,"34241":22366,"34242":22488,"34243":33556,"34244":22885,"34245":22920,"34246":29233,"34247":24574,"34248":24582,"34249":24698,"34250":25439,"34251":25250,"34252":25443,"34253":26500,"34254":26198,"34255":26197,"34256":26104,"34257":20250,"34258":19994,"34259":26497,"34260":26472,"34261":26722,"34262":26539,"34263":23681,"34264":27807,"34265":28781,"34266":28287,"34267":28369,"34268":27815,"34269":28902,"34270":28860,"34271":28800,"34272":28949,"34273":29239,"34274":29422,"34275":29502,"34276":29682,"34277":24403,"34278":30415,"34279":30544,"34280":30529,"34281":38606,"34282":30860,"34283":33410,"34284":31509,"34285":31908,"34286":32463,"34287":32482,"34288":32465,"34289":32485,"34290":32486,"34291":20041,"34292":32673,"34293":22307,"34294":32928,"34295":33050,"34296":32959,"34297":33041,"34298":33636,"34299":33479,"34300":21494,"34301":33716,"34302":34398,"34368":34383,"34369":21495,"34370":34568,"34371":34476,"34372":34917,"34373":35013,"34374":35815,"34375":35813,"34376":35814,"34377":35797,"34378":35799,"34379":35800,"34380":35801,"34381":35811,"34382":35802,"34383":35805,"34384":35803,"34385":35809,"34386":35810,"34387":35808,"34388":35807,"34389":36156,"34390":36164,"34391":36158,"34392":36159,"34393":36160,"34394":36161,"34395":36162,"34396":36165,"34397":36739,"34398":36733,"34399":36732,"34400":36734,"34401":20892,"34402":36816,"34403":36798,"34404":36829,"34405":36807,"34406":37049,"34407":38068,"34408":38067,"34409":38073,"34410":38072,"34411":38078,"34412":38080,"34413":38085,"34414":38057,"34415":38082,"34416":38083,"34417":38089,"34418":38091,"34419":38044,"34420":38093,"34421":38079,"34422":38086,"34423":38392,"34424":38504,"34425":38589,"34426":30005,"34427":39044,"34428":39037,"34429":39039,"34430":39036,"34465":39041,"34466":39042,"34467":39282,"34468":39284,"34469":39281,"34470":39280,"34471":39536,"34472":39534,"34473":39535,"34474":40480,"34475":20389,"34476":20392,"34477":21294,"34478":21388,"34479":23581,"34480":21589,"34481":21497,"34482":21949,"34483":21863,"34484":21716,"34485":22242,"34486":22270,"34487":23576,"34488":22443,"34489":22545,"34490":23551,"34491":26790,"34492":22842,"34493":22849,"34494":22954,"34495":23454,"34496":23517,"34497":23545,"34498":23649,"34499":23853,"34500":23702,"34501":24065,"34502":24124,"34503":24443,"34504":24577,"34505":24815,"34506":24696,"34507":24813,"34508":24808,"34509":25602,"34510":25524,"34511":25530,"34512":30021,"34513":33635,"34514":26538,"34515":28378,"34516":28173,"34517":27721,"34518":28385,"34519":28382,"34520":28176,"34521":28072,"34522":28063,"34523":27818,"34524":28180,"34525":28183,"34526":28068,"34527":33639,"34528":23572,"34529":33638,"34530":29425,"34531":29712,"34532":29595,"34533":30111,"34534":30113,"34535":30127,"34536":30186,"34537":23613,"34538":30417,"34539":30805,"34540":31087,"34541":31096,"34542":31181,"34543":31216,"34544":27964,"34545":31389,"34546":31546,"34547":31581,"34548":32509,"34549":32510,"34550":32508,"34551":32496,"34552":32491,"34553":32511,"34554":32039,"34555":32512,"34556":32434,"34557":32494,"34558":32504,"34624":32501,"34625":32438,"34626":32500,"34627":32490,"34628":32513,"34629":32502,"34630":32602,"34631":38395,"34632":33669,"34633":30422,"34634":33642,"34635":33485,"34636":34432,"34637":35829,"34638":35821,"34639":35820,"34640":35748,"34641":35819,"34642":35823,"34643":35828,"34644":35824,"34645":35826,"34646":35825,"34647":35827,"34648":35822,"34649":23486,"34650":36168,"34651":36170,"34652":36213,"34653":36214,"34654":36741,"34655":36740,"34656":36731,"34657":36828,"34658":36874,"34659":36882,"34660":38128,"34661":38134,"34662":38108,"34663":38125,"34664":38114,"34665":38124,"34666":38120,"34667":38133,"34668":38115,"34669":38402,"34670":38394,"34671":38397,"34672":38401,"34673":38400,"34674":38469,"34675":39047,"34676":39046,"34677":39122,"34678":39290,"34679":39292,"34680":39285,"34681":39287,"34682":39539,"34683":32942,"34684":39600,"34685":40483,"34686":40482,"34721":20964,"34722":40784,"34723":20159,"34724":20202,"34725":20215,"34726":20396,"34727":20393,"34728":20461,"34729":21095,"34730":21016,"34731":21073,"34732":21053,"34733":21385,"34734":21792,"34735":22068,"34736":21719,"34737":22040,"34738":21943,"34739":21880,"34740":21501,"34741":22687,"34742":22367,"34743":22368,"34744":22549,"34745":23092,"34746":23157,"34747":22953,"34748":23047,"34749":23046,"34750":23485,"34751":23457,"34752":20889,"34753":23618,"34754":23956,"34755":24092,"34756":24223,"34757":21416,"34758":24217,"34759":21422,"34760":24191,"34761":24377,"34762":24198,"34763":34385,"34764":24551,"34765":24578,"34766":24751,"34767":24814,"34768":24868,"34769":24579,"34770":25370,"34771":25169,"34772":25438,"34773":25320,"34774":25376,"34775":25242,"34776":25528,"34777":25599,"34778":25932,"34779":25968,"34780":26242,"34781":26165,"34782":26679,"34783":26729,"34784":26530,"34785":26631,"34786":27004,"34787":26728,"34788":20048,"34789":26526,"34790":27431,"34791":27527,"34792":27572,"34793":27974,"34794":27900,"34795":27905,"34796":27975,"34797":28291,"34798":28070,"34799":28071,"34800":27988,"34801":28909,"34802":22870,"34803":33721,"34804":30126,"34805":30353,"34806":30385,"34807":30424,"34808":30830,"34809":30721,"34810":31377,"34811":31351,"34812":32532,"34813":32451,"34814":32428,"34880":32516,"34881":32517,"34882":32521,"34883":32534,"34884":32536,"34885":32447,"34886":32526,"34887":32531,"34888":32525,"34889":32514,"34890":32520,"34891":32519,"34892":39554,"34893":32610,"34894":33014,"34895":32932,"34896":33714,"34897":33643,"34898":33931,"34899":34430,"34900":34583,"34901":21355,"34902":35850,"34903":35845,"34904":35848,"34905":35846,"34906":35806,"34907":35831,"34908":35832,"34909":35838,"34910":35839,"34911":35844,"34912":35843,"34913":35841,"34914":35770,"34915":35812,"34916":35847,"34917":35837,"34918":35840,"34919":31446,"34920":36180,"34921":36175,"34922":36171,"34923":36145,"34924":36134,"34925":36172,"34926":36132,"34927":21334,"34928":36176,"34929":36136,"34930":36179,"34931":36341,"34932":36745,"34933":36742,"34934":36749,"34935":36744,"34936":36743,"34937":36718,"34938":36750,"34939":36747,"34940":36746,"34941":36866,"34942":36801,"34977":37051,"34978":37073,"34979":37011,"34980":38156,"34981":38161,"34982":38144,"34983":38138,"34984":38096,"34985":38148,"34986":38109,"34987":38160,"34988":38153,"34989":38155,"34990":38049,"34991":38146,"34992":38398,"34993":38405,"34994":24041,"34995":39049,"34996":39052,"34997":20859,"34998":39295,"34999":39297,"35000":39548,"35001":39547,"35002":39543,"35003":39542,"35004":39549,"35005":39550,"35006":39545,"35007":39544,"35008":39607,"35009":38393,"35010":40063,"35011":40065,"35012":40489,"35013":40486,"35014":40632,"35015":40831,"35016":20454,"35017":20647,"35018":20394,"35019":24130,"35020":21058,"35021":21544,"35022":21725,"35023":22003,"35024":22438,"35025":22363,"35026":22859,"35027":34949,"35028":23398,"35029":23548,"35030":23466,"35031":20973,"35032":24811,"35033":25044,"35034":24518,"35035":25112,"35036":25317,"35037":25377,"35038":25374,"35039":25454,"35040":25523,"35041":25321,"35042":25441,"35043":25285,"35044":25373,"35045":21382,"35046":26195,"35047":26196,"35048":26137,"35049":26726,"35050":27178,"35051":26641,"35052":26925,"35053":26725,"35054":26426,"35055":26721,"35056":28096,"35057":27987,"35058":27901,"35059":27978,"35060":27811,"35061":28582,"35062":28177,"35063":28861,"35064":28903,"35065":28783,"35066":28907,"35067":28950,"35068":29420,"35069":29585,"35070":29935,"35136":30232,"35137":21346,"35138":30610,"35139":30742,"35140":30875,"35141":31215,"35142":39062,"35143":31267,"35144":31397,"35145":31491,"35146":31579,"35147":32546,"35148":32547,"35149":33830,"35150":32538,"35151":21439,"35152":32543,"35153":32540,"35154":32537,"35155":32457,"35156":33147,"35157":20852,"35158":33329,"35159":33633,"35160":33831,"35161":33436,"35162":34434,"35163":33828,"35164":35044,"35165":20146,"35166":35278,"35167":35867,"35168":35866,"35169":35855,"35170":35763,"35171":35851,"35172":35853,"35173":35856,"35174":35864,"35175":35834,"35176":35858,"35177":35859,"35178":35773,"35179":35861,"35180":35865,"35181":35852,"35182":35862,"35183":36182,"35184":36752,"35185":36753,"35186":36755,"35187":36751,"35188":21150,"35189":36873,"35190":36831,"35191":36797,"35192":36951,"35193":37050,"35194":38189,"35195":38191,"35196":38192,"35197":38169,"35198":38065,"35233":38050,"35234":38177,"35235":24405,"35236":38126,"35237":38181,"35238":38182,"35239":38175,"35240":38178,"35241":38193,"35242":38414,"35243":38543,"35244":38505,"35245":38745,"35246":33148,"35247":39050,"35248":39048,"35249":39057,"35250":39060,"35251":22836,"35252":39059,"35253":39056,"35254":39302,"35255":39279,"35256":39300,"35257":39301,"35258":39559,"35259":39560,"35260":39558,"35261":39608,"35262":39612,"35263":40077,"35264":40501,"35265":40490,"35266":40495,"35267":40493,"35268":40499,"35269":40857,"35270":40863,"35271":20248,"35272":20607,"35273":20648,"35274":21169,"35275":21659,"35276":21523,"35277":21387,"35278":22489,"35279":23156,"35280":23252,"35281":23351,"35282":23604,"35283":23654,"35284":23679,"35285":23896,"35286":24110,"35287":24357,"35288":24212,"35289":24691,"35290":25103,"35291":20987,"35292":25380,"35293":25319,"35294":25311,"35295":25601,"35296":25947,"35297":27609,"35298":26279,"35299":26723,"35300":26816,"35301":26727,"35302":26633,"35303":27183,"35304":27539,"35305":27617,"35306":27870,"35307":28392,"35308":27982,"35309":28059,"35310":28389,"35311":28073,"35312":28493,"35313":33829,"35314":28799,"35315":28891,"35316":28905,"35317":22681,"35318":29406,"35319":33719,"35320":29615,"35321":29815,"35322":30184,"35323":30103,"35324":30699,"35325":30970,"35326":30710,"35392":31699,"35393":31914,"35394":38214,"35395":31937,"35396":32553,"35397":32489,"35398":32554,"35399":32533,"35400":32551,"35401":32503,"35402":32541,"35403":24635,"35404":32437,"35405":32555,"35406":32420,"35407":32549,"35408":32358,"35409":32550,"35410":22768,"35411":32874,"35412":32852,"35413":32824,"35414":33043,"35415":32966,"35416":33080,"35417":33037,"35418":20020,"35419":20030,"35420":33392,"35421":34103,"35422":34015,"35423":20111,"35424":34684,"35425":34632,"35426":20149,"35427":35099,"35428":35274,"35429":35868,"35430":35876,"35431":35878,"35432":35762,"35433":35854,"35434":35875,"35435":35874,"35436":35466,"35437":35879,"35438":36186,"35439":36187,"35440":36141,"35441":36185,"35442":36235,"35443":36758,"35444":36759,"35445":27586,"35446":36757,"35447":33286,"35448":36824,"35449":36808,"35450":37213,"35451":38208,"35452":38209,"35453":38170,"35454":38190,"35489":38194,"35490":38149,"35491":38180,"35492":38202,"35493":38201,"35494":38203,"35495":38206,"35496":38199,"35497":38420,"35498":38421,"35499":38417,"35500":38385,"35501":38544,"35502":38582,"35503":34429,"35504":38889,"35505":39063,"35506":39123,"35507":39563,"35508":39567,"35509":40092,"35510":40091,"35511":40084,"35512":40081,"35513":40511,"35514":40509,"35515":28857,"35516":25995,"35517":19995,"35518":22108,"35519":22329,"35520":22418,"35521":23158,"35522":25041,"35523":25193,"35524":25527,"35525":25200,"35526":25781,"35527":25670,"35528":25822,"35529":25783,"35530":26029,"35531":27103,"35532":26588,"35533":27099,"35534":26592,"35535":27428,"35536":24402,"35537":27553,"35538":27899,"35539":28182,"35540":28388,"35541":28174,"35542":28293,"35543":27983,"35544":28908,"35545":28952,"35546":29367,"35547":29454,"35548":29934,"35549":30112,"35550":30545,"35551":30784,"35552":31036,"35553":31313,"35554":31229,"35555":31388,"35556":31373,"35557":31659,"35558":31783,"35559":31658,"35560":31697,"35561":31616,"35562":31918,"35563":32455,"35564":32558,"35565":32469,"35566":32557,"35567":32483,"35568":32559,"35569":32728,"35570":32844,"35571":32834,"35572":33040,"35573":33169,"35574":26087,"35575":33832,"35576":34013,"35577":33632,"35578":34546,"35579":34633,"35580":35280,"35581":35294,"35582":35871,"35648":35880,"35649":35884,"35650":35882,"35651":36184,"35652":36434,"35653":36857,"35654":36344,"35655":36527,"35656":36716,"35657":36761,"35658":36841,"35659":21307,"35660":37233,"35661":38225,"35662":38145,"35663":38056,"35664":38221,"35665":38215,"35666":38224,"35667":38226,"35668":38217,"35669":38422,"35670":38383,"35671":38423,"35672":38425,"35673":26434,"35674":21452,"35675":38607,"35676":40481,"35677":39069,"35678":39068,"35679":39064,"35680":39066,"35681":39067,"35682":39311,"35683":39306,"35684":39304,"35685":39569,"35686":39617,"35687":40104,"35688":40100,"35689":40107,"35690":40103,"35691":40515,"35692":40517,"35693":40516,"35694":22404,"35695":22364,"35696":23456,"35697":24222,"35698":24208,"35699":24809,"35700":24576,"35701":25042,"35702":25314,"35703":26103,"35704":27249,"35705":26911,"35706":27016,"35707":27257,"35708":28487,"35709":28625,"35710":27813,"35745":28626,"35746":27896,"35747":28865,"35748":29261,"35749":29322,"35750":20861,"35751":29549,"35752":29626,"35753":29756,"35754":30068,"35755":30250,"35756":30861,"35757":31095,"35758":31283,"35759":31614,"35760":33575,"35761":32462,"35762":32499,"35763":32472,"35764":32599,"35765":32564,"35766":33211,"35767":33402,"35768":34222,"35769":33647,"35770":34433,"35771":34631,"35772":35014,"35773":34948,"35774":35889,"35775":35782,"35776":35885,"35777":35890,"35778":35749,"35779":35887,"35780":36192,"35781":36190,"35782":36343,"35783":36762,"35784":36735,"35785":36766,"35786":36793,"35787":38236,"35788":38237,"35789":38238,"35790":38142,"35791":38231,"35792":38232,"35793":38230,"35794":38233,"35795":38197,"35796":38210,"35797":38143,"35798":37694,"35799":20851,"35800":38471,"35801":38590,"35802":38654,"35803":38892,"35804":38901,"35805":31867,"35806":39072,"35807":39125,"35808":39314,"35809":39313,"35810":39579,"35811":39575,"35812":40120,"35813":40115,"35814":40109,"35815":40119,"35816":40529,"35817":40521,"35818":40522,"35819":40524,"35820":40527,"35821":20029,"35822":40628,"35823":21149,"35824":21657,"35825":22052,"35826":20005,"35827":23453,"35828":24748,"35829":24527,"35830":25318,"35831":25600,"35832":32999,"35833":27015,"35834":28572,"35835":28491,"35836":28809,"35837":29649,"35838":30719,"35904":30778,"35905":30718,"35906":30782,"35907":31398,"35908":31454,"35909":31609,"35910":31726,"35911":36779,"35912":32548,"35913":32487,"35914":32578,"35915":33002,"35916":33328,"35917":34108,"35918":34106,"35919":33446,"35920":33529,"35921":34164,"35922":34461,"35923":35124,"35924":35273,"35925":35302,"35926":35758,"35927":35793,"35928":35893,"35929":36194,"35930":36193,"35931":36280,"35932":37322,"35933":38047,"35934":38105,"35935":38152,"35936":38416,"35937":39128,"35938":39286,"35939":39269,"35940":39582,"35941":33150,"35942":39578,"35943":40131,"35944":40133,"35945":20826,"35946":40835,"35947":40836,"35948":20458,"35949":21995,"35950":21869,"35951":22179,"35952":23646,"35953":24807,"35954":24913,"35955":25668,"35956":25658,"35957":26003,"35958":27185,"35959":26639,"35960":26818,"35961":27516,"35962":28866,"35963":29306,"35964":38262,"35965":29838,"35966":30302,"36001":32544,"36002":32493,"36003":20848,"36004":34259,"36005":34510,"36006":35272,"36007":35892,"36008":25252,"36009":35465,"36010":36163,"36011":36364,"36012":36291,"36013":36347,"36014":36720,"36015":36777,"36016":38256,"36017":38253,"36018":38081,"36019":38107,"36020":38094,"36021":38255,"36022":38220,"36023":21709,"36024":39038,"36025":39074,"36026":39144,"36027":39537,"36028":39584,"36029":34022,"36030":39585,"36031":39621,"36032":40141,"36033":40143,"36034":33722,"36035":40548,"36036":40542,"36037":40839,"36038":40840,"36039":21870,"36040":20456,"36041":20645,"36042":21587,"36043":23402,"36044":24005,"36045":23782,"36046":24367,"36047":25674,"36048":26435,"36049":27426,"36050":28393,"36051":29473,"36052":21472,"36053":30270,"36054":30307,"36055":31548,"36056":31809,"36057":32843,"36058":33039,"36059":34989,"36060":34924,"36061":35835,"36062":36174,"36063":36189,"36064":36399,"36065":36396,"36066":36756,"36067":37094,"36068":38136,"36069":37492,"36070":38657,"36071":38801,"36072":32366,"36073":39076,"36074":39556,"36075":39553,"36076":40150,"36077":40098,"36078":40148,"36079":40151,"36080":40551,"36081":40485,"36082":40761,"36083":40841,"36084":40842,"36085":40858,"36086":24651,"36087":25371,"36088":25605,"36089":29906,"36090":31363,"36091":32552,"36092":33250,"36093":33821,"36094":34506,"36160":21464,"36161":36902,"36162":36923,"36163":38259,"36164":38084,"36165":38757,"36166":26174,"36167":39181,"36168":24778,"36169":39551,"36170":39564,"36171":39635,"36172":39633,"36173":40157,"36174":40158,"36175":40156,"36176":40502,"36177":22065,"36178":22365,"36179":25597,"36180":30251,"36181":30315,"36182":32641,"36183":34453,"36184":35753,"36185":35863,"36186":35894,"36187":33395,"36188":36195,"36189":37247,"36190":38643,"36191":28789,"36192":38701,"36193":39078,"36194":39588,"36195":39699,"36196":39751,"36197":40078,"36198":40560,"36199":40557,"36200":30839,"36201":30416,"36202":40140,"36203":40844,"36204":40843,"36205":21381,"36206":27012,"36207":28286,"36208":31729,"36209":31657,"36210":34542,"36211":35266,"36212":36433,"36213":34885,"36214":38053,"36215":39045,"36216":39307,"36217":39627,"36218":40649,"36219":28390,"36220":30633,"36221":38218,"36222":38831,"36257":39540,"36258":39589,"36259":32518,"36260":35872,"36261":36495,"36262":37245,"36263":38075,"36264":37550,"36265":38179,"36266":40132,"36267":40072,"36268":40681,"36269":20991,"36270":40550,"36271":39562,"36272":40563,"36273":40510,"36274":38074,"36275":20162,"36276":34381,"36277":27538,"36278":22439,"36279":22395,"36280":25099,"36281":20451,"36282":21037,"36283":21389,"36284":21593,"36285":21370,"36286":32424,"36287":33543,"36288":38023,"36289":38022,"36290":21591,"36291":24362,"36292":31059,"36293":32446,"36294":37071,"36295":38028,"36296":21072,"36297":21286,"36298":22261,"36299":22445,"36300":23045,"36301":23741,"36302":23811,"36303":28062,"36304":28172,"36305":28867,"36306":30502,"36307":32448,"36308":32464,"36309":33003,"36310":38030,"36311":38032,"36312":38037,"36313":38029,"36314":38379,"36315":22955,"36316":23899,"36317":24701,"36318":26720,"36319":26536,"36320":27817,"36321":27976,"36322":30066,"36323":30743,"36324":32471,"36325":33757,"36326":35271,"36327":35765,"36328":35790,"36329":35794,"36330":36150,"36331":36147,"36332":36730,"36333":36725,"36334":36728,"36335":36911,"36336":37075,"36337":37124,"36338":38059,"36339":38060,"36340":38043,"36341":38063,"36342":38061,"36343":38058,"36344":38390,"36345":38503,"36346":39032,"36347":39275,"36348":40697,"36349":20251,"36350":20603,"36416":20325,"36417":21794,"36418":22450,"36419":24047,"36420":24493,"36421":28828,"36422":33557,"36423":29426,"36424":29614,"36425":32488,"36426":32480,"36427":32481,"36428":32671,"36429":33645,"36430":34545,"36431":35795,"36432":35798,"36433":35817,"36434":35796,"36435":35804,"36436":36241,"36437":36738,"36438":36737,"36439":37036,"36440":38090,"36441":38088,"36442":38064,"36443":38066,"36444":38070,"36445":38157,"36446":38092,"36447":38077,"36448":38076,"36449":39043,"36450":39040,"36451":20971,"36452":40702,"36453":20606,"36454":21787,"36455":23901,"36456":24123,"36457":24747,"36458":24749,"36459":24580,"36460":25132,"36461":25111,"36462":25247,"36463":25248,"36464":25532,"36465":26724,"36466":26473,"36467":33637,"36468":27986,"36469":27812,"36470":28829,"36471":30386,"36472":30720,"36473":32507,"36474":32498,"36475":32495,"36476":32506,"36477":33715,"36478":35275,"36513":35830,"36514":36167,"36515":38129,"36516":38098,"36517":38097,"36518":38101,"36519":38111,"36520":38123,"36521":38127,"36522":38122,"36523":38135,"36524":38102,"36525":38117,"36526":39121,"36527":21055,"36528":21154,"36529":21715,"36530":21586,"36531":23810,"36532":23780,"36533":24209,"36534":24870,"36535":25378,"36536":26912,"36537":27637,"36538":39053,"36539":28061,"36540":28514,"36541":28064,"36542":28375,"36543":29711,"36544":29825,"36545":30231,"36546":32515,"36547":32535,"36548":32524,"36549":32527,"36550":32529,"36551":33628,"36552":33932,"36553":33553,"36554":33473,"36555":35833,"36556":35836,"36557":35842,"36558":36181,"36559":37112,"36560":38162,"36561":38103,"36562":38141,"36563":38163,"36564":38154,"36565":38116,"36566":38150,"36567":38151,"36568":38164,"36569":38406,"36570":38403,"36571":38739,"36572":39055,"36573":39293,"36574":39541,"36575":39552,"36576":40066,"36577":40488,"36578":21714,"36579":21717,"36580":21721,"36581":23250,"36582":23748,"36583":24639,"36584":27546,"36585":27981,"36586":28904,"36587":29443,"36588":29423,"36589":30876,"36590":31405,"36591":32279,"36592":32539,"36593":33927,"36594":33640,"36595":33929,"36596":33630,"36597":33720,"36598":33431,"36599":34547,"36600":35816,"36601":35857,"36602":35860,"36603":35869,"36604":37072,"36605":38185,"36606":38188,"36672":38166,"36673":38167,"36674":38140,"36675":38171,"36676":38165,"36677":38174,"36678":38036,"36679":38415,"36680":38408,"36681":38409,"36682":38410,"36683":38412,"36684":38413,"36685":40498,"36686":40497,"36687":21724,"36688":24113,"36689":24697,"36690":25672,"36691":58305,"36692":27894,"36693":29461,"36694":29971,"36695":30213,"36696":30187,"36697":30807,"36698":31654,"36699":31578,"36700":31976,"36701":32545,"36702":32807,"36703":33631,"36704":33718,"36705":34544,"36706":35042,"36707":35279,"36708":35873,"36709":35788,"36710":35877,"36711":36292,"36712":38200,"36713":38196,"36714":38113,"36715":38198,"36716":38418,"36717":39271,"36718":40082,"36719":40085,"36720":40504,"36721":40505,"36722":40506,"36723":40832,"36724":24636,"36725":25669,"36726":25784,"36727":27898,"36728":30102,"36729":32523,"36730":32873,"36731":33641,"36732":34789,"36733":34414,"36734":35764,"36769":35881,"36770":36188,"36771":36157,"36772":36760,"36773":37021,"36774":38227,"36775":38112,"36776":38204,"36777":38223,"36778":34021,"36779":38890,"36780":39273,"36781":39568,"36782":39570,"36783":39571,"36784":38411,"36785":40105,"36786":40096,"36787":40520,"36788":40513,"36789":40518,"36790":21411,"36791":21590,"36792":22406,"36793":27104,"36794":26638,"36795":27655,"36796":27895,"36797":28486,"36798":31074,"36799":32562,"36800":32563,"36801":32628,"36802":33315,"36803":34511,"36804":34431,"36805":35043,"36806":35281,"36807":35311,"36808":35886,"36809":38235,"36810":38239,"36811":38250,"36812":38214,"36813":38121,"36814":38891,"36815":39073,"36816":39312,"36817":39618,"36818":40117,"36819":40118,"36820":40123,"36821":40113,"36822":40526,"36823":40491,"36824":40700,"36825":21950,"36826":25732,"36827":26634,"36828":26533,"36829":26636,"36830":32561,"36831":32845,"36832":33551,"36833":33480,"36834":34162,"36835":34548,"36836":34686,"36837":38132,"36838":38246,"36839":38248,"36840":38241,"36841":38243,"36842":38212,"36843":38251,"36844":38119,"36845":38244,"36846":38137,"36847":38426,"36848":39071,"36849":39316,"36850":39546,"36851":39581,"36852":39583,"36853":39576,"36854":40535,"36855":40538,"36856":40540,"36857":40838,"36858":40837,"36859":20649,"36860":23743,"36861":30152,"36862":25786,"36928":27017,"36929":28384,"36930":30779,"36931":31901,"36932":32425,"36933":32556,"36934":34105,"36935":36166,"36936":38257,"36937":38396,"36938":39129,"36939":39586,"36940":39574,"36941":39580,"36942":40101,"36943":40142,"36944":40144,"36945":40547,"36946":40536,"36947":40574,"36948":20865,"36949":23048,"36950":28757,"36951":25874,"36952":30271,"36953":31656,"36954":31860,"36955":33339,"36956":35276,"36957":36345,"36958":36318,"36959":36729,"36960":38228,"36961":38252,"36962":39587,"36963":39557,"36964":40149,"36965":40099,"36966":40102,"36967":40552,"36968":40503,"36969":40859,"36970":26686,"36971":26916,"36972":34016,"36973":38624,"36974":36723,"36975":40159,"36976":40095,"36977":40553,"36978":40556,"36979":40554,"36980":40555,"36981":40519,"36982":28751,"36983":31766,"36984":35888,"36985":39628,"36986":31550,"36987":31900,"36988":32565,"36989":33044,"36990":36479,"37025":38247,"37026":40090,"37027":36273,"37028":36508,"37029":37246,"37030":35891,"37031":39070,"37032":39079,"37033":39591,"37034":40492,"37035":25094,"37036":38404,"37037":40097,"37038":40514,"37039":31160,"37040":25300,"37041":36299,"37042":29648,"37043":23467,"37044":25296,"37045":27585,"37046":20943,"37047":31108,"37048":21525,"37049":28508,"37050":34972,"37051":37095,"37052":20857,"37053":25144,"37054":25243,"37055":25383,"37056":25531,"37057":25566,"37058":25594,"37059":25745,"37060":25792,"37061":25825,"37062":25846,"37063":25861,"37064":25909,"37065":25934,"37066":25963,"37067":25992,"37068":26073,"37069":26142,"37070":26171,"37071":26175,"37072":26180,"37073":26199,"37074":26217,"37075":26227,"37076":26243,"37077":26300,"37078":26303,"37079":26305,"37080":26357,"37081":26362,"37082":26363,"37083":26382,"37084":26390,"37085":26423,"37086":26468,"37087":26470,"37088":26534,"37089":26535,"37090":26537,"37091":26619,"37092":26621,"37093":26624,"37094":26625,"37095":26629,"37096":26654,"37097":26698,"37098":26706,"37099":26709,"37100":26713,"37101":26765,"37102":26809,"37103":26831,"37104":20616,"37105":38184,"37106":40087,"37107":26914,"37108":26918,"37109":220,"37110":58591,"37111":58592,"37112":252,"37113":58594,"37114":58595,"37115":220,"37116":252,"37117":26934,"37118":26977,"37184":33477,"37185":33482,"37186":33496,"37187":33560,"37188":33562,"37189":33571,"37190":33606,"37191":33627,"37192":33634,"37193":33644,"37194":33646,"37195":33692,"37196":33695,"37197":33717,"37198":33724,"37199":33783,"37200":33834,"37201":33864,"37202":33884,"37203":33890,"37204":33924,"37205":33928,"37206":34012,"37207":34019,"37208":34104,"37209":34138,"37210":34199,"37211":34219,"37212":34241,"37213":34323,"37214":34326,"37215":8715,"37216":34581,"37217":34672,"37218":34685,"37219":34699,"37220":34728,"37221":34759,"37222":34768,"37223":34823,"37224":34830,"37225":34855,"37226":34990,"37227":8712,"37228":34997,"37229":35007,"37230":35045,"37231":35061,"37232":35100,"37233":35101,"37234":35191,"37235":35303,"37236":35383,"37237":35500,"37238":35546,"37239":35675,"37240":35697,"37241":35883,"37242":35898,"37243":35964,"37244":35982,"37245":36014,"37246":36114,"37281":36169,"37282":36173,"37283":36209,"37284":36360,"37285":36410,"37286":36464,"37287":36505,"37288":36528,"37289":36529,"37290":36549,"37291":36550,"37292":36558,"37293":36579,"37294":36620,"37295":36721,"37296":36727,"37297":36775,"37298":36847,"37299":36878,"37300":36921,"37301":36965,"37302":37001,"37303":37086,"37304":37141,"37305":37334,"37306":37339,"37307":37342,"37308":37345,"37309":37349,"37310":37366,"37311":37372,"37312":37417,"37313":37420,"37314":65287,"37315":37465,"37316":37495,"37317":37613,"37318":37690,"37319":58701,"37320":58702,"37321":29227,"37322":20866,"37323":20886,"37324":20023,"37325":20843,"37326":20799,"37327":58709,"37328":58710,"37329":26409,"37330":27706,"37331":21378,"37332":30098,"37333":32896,"37334":34916,"37335":19974,"37336":58718,"37337":58719,"37338":58720,"37339":11927,"37340":21241,"37341":21269,"37342":8225,"37343":58725,"37344":13316,"37345":58727,"37346":58728,"37347":58729,"37348":58730,"37349":58731,"37350":20981,"37351":58733,"37352":23662,"37353":58735,"37354":22231,"37355":20128,"37356":20907,"37357":11904,"37358":27079,"37359":58741,"37360":9550,"37361":9688,"37362":9689,"37363":9794,"37364":9654,"37365":9668,"37366":8597,"37367":8252,"37368":182,"37369":8704,"37370":8616,"37371":8596,"37372":8962,"37373":58755,"37374":58756,"37440":20124,"37441":24746,"37442":22311,"37443":22258,"37444":21307,"37445":22769,"37446":36920,"37447":38560,"37448":26628,"37449":21942,"37450":39365,"37451":35585,"37452":20870,"37453":32257,"37454":24540,"37455":27431,"37456":27572,"37457":26716,"37458":22885,"37459":31311,"37460":20206,"37461":20385,"37462":30011,"37463":28784,"37464":20250,"37465":24724,"37466":28023,"37467":32117,"37468":22730,"37469":25040,"37470":25313,"37471":27579,"37472":35226,"37473":23398,"37474":27005,"37475":21917,"37476":28167,"37477":58794,"37478":24059,"37479":38501,"37480":21223,"37481":23515,"37482":28450,"37483":38306,"37484":27475,"37485":35251,"37486":27671,"37487":24112,"37488":25135,"37489":29344,"37490":34384,"37491":26087,"37492":24613,"37493":25312,"37494":25369,"37495":34394,"37496":23777,"37497":25375,"37498":29421,"37499":37111,"37500":38911,"37501":26241,"37502":21220,"37537":35641,"37538":21306,"37539":39366,"37540":21234,"37541":58824,"37542":24452,"37543":33550,"37544":24693,"37545":25522,"37546":28179,"37547":32076,"37548":34509,"37549":36605,"37550":32153,"37551":40335,"37552":25731,"37553":30476,"37554":20537,"37555":21091,"37556":38522,"37557":22287,"37558":26908,"37559":27177,"37560":38997,"37561":39443,"37562":21427,"37563":21577,"37564":23087,"37565":35492,"37566":24195,"37567":28207,"37568":37489,"37569":21495,"37570":22269,"37571":40658,"37572":31296,"37573":30741,"37574":28168,"37575":25998,"37576":27507,"37577":21092,"37578":38609,"37579":21442,"37580":26719,"37581":24808,"37582":36059,"37583":27531,"37584":27503,"37585":20816,"37586":36766,"37587":28287,"37588":23455,"37589":20889,"37590":33294,"37591":25448,"37592":37320,"37593":23551,"37594":21454,"37595":34886,"37596":24467,"37597":28171,"37598":29539,"37599":32294,"37600":31899,"37601":20966,"37602":23558,"37603":31216,"37604":28169,"37605":28988,"37606":22888,"37607":26465,"37608":29366,"37609":20055,"37610":27972,"37611":21104,"37612":30067,"37613":32260,"37614":22732,"37615":23330,"37616":35698,"37617":37304,"37618":35302,"37619":22065,"37620":23517,"37621":23613,"37622":22259,"37623":31883,"37624":37204,"37625":31298,"37626":38543,"37627":39620,"37628":26530,"37629":25968,"37630":25454,"37696":28716,"37697":22768,"37698":25993,"37699":38745,"37700":31363,"37701":25666,"37702":32118,"37703":23554,"37704":27973,"37705":25126,"37706":36341,"37707":37549,"37708":28508,"37709":36983,"37710":36984,"37711":32330,"37712":31109,"37713":30094,"37714":22766,"37715":20105,"37716":33624,"37717":25436,"37718":25407,"37719":24035,"37720":31379,"37721":35013,"37722":20711,"37723":23652,"37724":32207,"37725":39442,"37726":22679,"37727":24974,"37728":34101,"37729":36104,"37730":33235,"37731":23646,"37732":32154,"37733":22549,"37734":23550,"37735":24111,"37736":28382,"37737":28381,"37738":25246,"37739":27810,"37740":28655,"37741":21336,"37742":22022,"37743":22243,"37744":26029,"37745":24382,"37746":36933,"37747":26172,"37748":37619,"37749":24193,"37750":24500,"37751":32884,"37752":25074,"37753":22618,"37754":36883,"37755":37444,"37756":28857,"37757":36578,"37758":20253,"37793":38651,"37794":28783,"37795":24403,"37796":20826,"37797":30423,"37798":31282,"37799":38360,"37800":24499,"37801":27602,"37802":29420,"37803":35501,"37804":23626,"37805":38627,"37806":24336,"37807":24745,"37808":33075,"37809":25309,"37810":24259,"37811":22770,"37812":26757,"37813":21338,"37814":34180,"37815":40614,"37816":32283,"37817":30330,"37818":39658,"37819":25244,"37820":27996,"37821":27996,"37822":25935,"37823":25975,"37824":20398,"37825":25173,"37826":20175,"37827":36794,"37828":22793,"37829":27497,"37830":33303,"37831":31807,"37832":21253,"37833":23453,"37834":25265,"37835":27873,"37836":32990,"37837":30770,"37838":35914,"37839":39165,"37840":22696,"37841":27598,"37842":28288,"37843":33032,"37844":40665,"37845":35379,"37846":34220,"37847":36493,"37848":19982,"37849":35465,"37850":25671,"37851":27096,"37852":35617,"37853":26332,"37854":26469,"37855":38972,"37856":20081,"37857":35239,"37858":31452,"37859":38534,"37860":26053,"37861":20001,"37862":29471,"37863":32209,"37864":28057,"37865":22593,"37866":31036,"37867":21169,"37868":25147,"37869":38666,"37870":40802,"37871":26278,"37872":27508,"37873":24651,"37874":32244,"37875":37676,"37876":28809,"37877":21172,"37878":27004,"37879":37682,"37880":28286,"37881":24357,"37882":20096,"37883":26365,"37884":22985,"37885":23437,"37886":23947,"37952":27179,"37953":26907,"37954":21936,"37955":31874,"37956":36796,"37957":27018,"37958":21682,"37959":40235,"37960":38635,"37961":26905,"37962":25539,"37963":39364,"37964":20967,"37965":26626,"37966":36795,"37967":20685,"37968":23776,"37969":26627,"37970":20970,"37971":21250,"37972":30834,"37973":30033,"37974":30048,"37975":22138,"37976":37618,"37977":22592,"37978":26622,"37979":20451,"37980":26466,"37981":31870,"37982":21249,"37983":20452,"37984":20453,"37985":20969,"37986":21498,"37987":21720,"37988":22222,"37989":22310,"37990":22327,"37991":22328,"37992":22408,"37993":22451,"37994":22442,"37995":22448,"37996":22486,"37997":22640,"37998":22713,"37999":22743,"38000":23670,"38001":23740,"38002":23749,"38003":23742,"38004":23926,"38005":24342,"38006":24634,"38007":25525,"38008":26433,"38009":26467,"38010":26529,"38011":26810,"38012":26917,"38013":26920,"38014":27258,"38049":26915,"38050":26913,"38051":27006,"38052":27009,"38053":27101,"38054":27182,"38055":27250,"38056":27423,"38057":27615,"38058":28181,"38059":29077,"38060":29927,"38061":29938,"38062":29936,"38063":29937,"38064":29944,"38065":29957,"38066":30057,"38067":30314,"38068":30836,"38069":31437,"38070":31439,"38071":31445,"38072":31443,"38073":31457,"38074":31472,"38075":31490,"38076":31763,"38077":31767,"38078":31888,"38079":31917,"38080":31936,"38081":31960,"38082":32155,"38083":32261,"38084":32359,"38085":32387,"38086":32400,"38087":33188,"38088":33373,"38089":33826,"38090":34009,"38091":34352,"38092":34475,"38093":34543,"38094":34992,"38095":35011,"38096":35012,"38097":35076,"38098":59183,"38099":36542,"38100":36552,"38101":36684,"38102":36791,"38103":36826,"38104":36903,"38105":36950,"38106":37685,"38107":37691,"38108":37817,"38109":38282,"38110":38294,"38111":38777,"38112":38790,"38113":38800,"38114":39082,"38115":39830,"38116":39831,"38117":39860,"38118":39887,"38119":39889,"38120":39890,"38121":39922,"38122":39921,"38123":39984,"38124":40007,"38125":40026,"38126":40176,"38127":40262,"38128":40292,"38129":40363,"38130":20036,"38131":21583,"38132":25368,"38133":39857,"38134":40041,"38135":40263,"38136":40293,"38137":39983,"38138":40639,"38139":20916,"38140":21610,"38141":26528,"38142":39822,"38208":37032,"38209":20914,"38210":13869,"38211":25285,"38212":21189,"38213":26545,"38214":21709,"38215":24658,"38216":21441,"38217":28913,"38218":22531,"38219":21855,"38220":37390,"38221":30528,"38222":29756,"38223":29002,"38224":28377,"38225":21472,"38226":29486,"38227":35023,"38228":30861,"38229":32675,"38230":32171,"38231":36394,"38232":37979,"38233":25452,"38234":24487,"38235":23557,"38236":32827,"38237":23791,"38238":14776,"38239":29009,"38240":36045,"38241":38894,"38242":22642,"38243":23139,"38244":32632,"38245":23895,"38246":24943,"38247":27032,"38248":32137,"38249":31918,"38250":32179,"38251":28545,"38252":23290,"38253":22715,"38254":29269,"38255":30286,"38256":36653,"38257":37561,"38258":40286,"38259":40623,"38260":32583,"38261":40388,"38262":36120,"38263":20915,"38264":34412,"38265":21668,"38266":21414,"38267":21030,"38268":26422,"38269":20001,"38270":21364,"38305":24313,"38306":21177,"38307":21647,"38308":24312,"38309":22956,"38310":24625,"38311":29248,"38312":33047,"38313":30267,"38314":24333,"38315":26187,"38316":26280,"38317":24932,"38318":25423,"38319":28895,"38320":27940,"38321":31911,"38322":31945,"38323":21465,"38324":25933,"38325":22338,"38326":29647,"38327":32966,"38328":13649,"38329":27445,"38330":30849,"38331":21452,"38332":29483,"38333":29482,"38334":29641,"38335":30026,"38336":23033,"38337":29124,"38338":29966,"38339":32220,"38340":39393,"38341":35241,"38342":28662,"38343":14935,"38344":25834,"38345":15341,"38346":27809,"38347":28284,"38348":30055,"38349":22633,"38350":22633,"38351":20996,"38352":59338,"38353":24967,"38354":25658,"38355":33263,"38356":59342,"38357":20917,"38358":20945,"38359":27769,"38360":22815,"38361":36857,"38362":39153,"38363":25911,"38364":33033,"38365":34996,"38366":14890,"38367":36525,"38368":32663,"38369":39440,"38370":32037,"38371":27336,"38372":20876,"38373":21031,"38374":59360,"38375":33050,"38376":21408,"38377":21410,"38378":27738,"38379":27703,"38380":33304,"38381":21894,"38382":24315,"38383":20937,"38384":30897,"38385":37474,"38386":21357,"38387":20931,"38388":59374,"38389":33905,"38390":35207,"38391":38765,"38392":35728,"38393":38563,"38394":24316,"38395":38583,"38396":20814,"38397":39952,"38398":26160,"38464":37461,"38465":30728,"38466":37701,"38467":37491,"38468":37737,"38469":59390,"38470":59391,"38471":59392,"38472":59393,"38473":37343,"38474":37338,"38475":30804,"38476":30822,"38477":30856,"38478":30902,"38479":30919,"38480":30930,"38481":30935,"38482":8491,"38483":8651,"38484":30948,"38485":30958,"38486":30960,"38487":30961,"38488":30965,"38489":31026,"38490":31027,"38491":31030,"38492":31064,"38493":12307,"38494":31065,"38495":31089,"38496":31102,"38497":31107,"38498":31110,"38499":31111,"38500":31121,"38501":31129,"38502":31135,"38503":31141,"38504":31202,"38505":31217,"38506":31220,"38507":31274,"38508":31290,"38509":31301,"38510":31333,"38511":31420,"38512":31426,"38513":31433,"38514":31451,"38515":31465,"38516":31486,"38517":31500,"38518":31527,"38519":31529,"38520":31554,"38521":31555,"38522":31573,"38523":31599,"38524":31666,"38525":27102,"38526":27129,"38561":37238,"38562":33114,"38563":33527,"38564":21579,"38565":33074,"38566":32957,"38567":33816,"38568":37214,"38569":37232,"38570":37260,"38571":33096,"38572":59459,"38573":17462,"38574":33113,"38575":32927,"38576":59463,"38577":21833,"38578":21537,"38579":21722,"38580":21554,"38581":21945,"38582":21652,"38583":59470,"38584":30802,"38585":30789,"38586":30796,"38587":59474,"38588":33981,"38589":33820,"38590":33476,"38591":59478,"38592":33915,"38593":35629,"38594":59481,"38595":22347,"38596":59483,"38597":59484,"38598":22341,"38599":34766,"38600":22112,"38601":21994,"38602":22139,"38603":32956,"38604":59491,"38605":30904,"38606":27148,"38607":21708,"38608":31696,"38609":31724,"38610":31738,"38611":31765,"38612":31771,"38613":31797,"38614":31812,"38615":31853,"38616":31886,"38617":31928,"38618":31939,"38619":31974,"38620":31981,"38621":31987,"38622":31989,"38623":31993,"38624":59511,"38625":31996,"38626":32139,"38627":32151,"38628":32164,"38629":32168,"38630":32205,"38631":32208,"38632":32211,"38633":32229,"38634":32253,"38635":27154,"38636":27170,"38637":27184,"38638":27190,"38639":27237,"38640":59527,"38641":59528,"38642":59529,"38643":59530,"38644":59531,"38645":59532,"38646":59533,"38647":59534,"38648":27251,"38649":27256,"38650":59537,"38651":59538,"38652":27260,"38653":27305,"38654":27306,"38720":9450,"38721":9312,"38722":9313,"38723":9314,"38724":9315,"38725":9316,"38726":9317,"38727":9318,"38728":9319,"38729":9320,"38730":9321,"38731":9322,"38732":9323,"38733":9324,"38734":9325,"38735":9326,"38736":9327,"38737":9328,"38738":9329,"38739":9330,"38740":9331,"38741":37700,"38742":37805,"38743":37830,"38744":37861,"38745":37914,"38746":37921,"38747":37950,"38748":37953,"38749":37971,"38750":37978,"38751":38042,"38752":38071,"38753":38104,"38754":38110,"38755":38131,"38756":38147,"38757":38158,"38758":38159,"38759":38168,"38760":38173,"38761":38186,"38762":38187,"38763":38207,"38764":38213,"38765":38222,"38766":38242,"38767":38245,"38768":38249,"38769":38258,"38770":38279,"38771":38297,"38772":38304,"38773":38322,"38774":38502,"38775":38557,"38776":38575,"38777":38578,"38778":38707,"38779":38715,"38780":38733,"38781":38735,"38782":38737,"38817":38741,"38818":38756,"38819":38763,"38820":38769,"38821":38802,"38822":38834,"38823":38898,"38824":38973,"38825":38996,"38826":39077,"38827":39107,"38828":39130,"38829":39150,"38830":39197,"38831":39200,"38832":39267,"38833":39296,"38834":39303,"38835":39309,"38836":39315,"38837":39317,"38838":39356,"38839":39368,"38840":39410,"38841":39606,"38842":39641,"38843":39646,"38844":39695,"38845":39753,"38846":39794,"38847":39811,"38848":39839,"38849":39867,"38850":39907,"38851":39925,"38852":39936,"38853":39940,"38854":39963,"38855":9398,"38856":9399,"38857":9400,"38858":9401,"38859":9402,"38860":9403,"38861":9404,"38862":9405,"38863":9406,"38864":9407,"38865":9408,"38866":9409,"38867":9410,"38868":9411,"38869":9412,"38870":9413,"38871":9414,"38872":9415,"38873":9416,"38874":9417,"38875":9418,"38876":9419,"38877":9420,"38878":9421,"38879":9422,"38880":9423,"38881":9424,"38882":9425,"38883":9426,"38884":9427,"38885":9428,"38886":9429,"38887":9430,"38888":9431,"38889":9432,"38890":9433,"38891":9434,"38892":9435,"38893":9436,"38894":9437,"38895":9438,"38896":9439,"38897":9440,"38898":9441,"38899":9442,"38900":9443,"38901":9444,"38902":9445,"38903":9446,"38904":9447,"38905":9448,"38906":9449,"38907":174,"38908":8482,"38909":59697,"38910":59698,"38976":40054,"38977":10122,"38978":10123,"38979":10124,"38980":10125,"38981":10126,"38982":10127,"38983":10128,"38984":10129,"38985":10130,"38986":10131,"38987":40069,"38988":40070,"38989":40071,"38990":40075,"38991":40080,"38992":40094,"38993":40110,"38994":40112,"38995":40114,"38996":40116,"38997":40122,"38998":40124,"38999":40125,"39000":40134,"39001":40135,"39002":40138,"39003":40139,"39004":40147,"39005":40152,"39006":40153,"39007":40162,"39008":40171,"39009":40172,"39010":40234,"39011":40264,"39012":40272,"39013":40314,"39014":40390,"39015":40523,"39016":40533,"39017":40539,"39018":40561,"39019":40618,"39020":40637,"39021":40644,"39022":40674,"39023":40682,"39024":40712,"39025":40715,"39026":40717,"39027":40737,"39028":40772,"39029":40785,"39030":40861,"39031":64014,"39032":64015,"39033":64017,"39034":64019,"39035":64020,"39036":64024,"39037":64031,"39038":64032,"39073":64033,"39074":64035,"39075":64036,"39076":64039,"39077":64040,"39078":64041,"39079":19972,"39080":20015,"39081":20097,"39082":20103,"39083":20131,"39084":20151,"39085":20156,"39086":20216,"39087":20264,"39088":20265,"39089":20279,"39090":20290,"39091":20293,"39092":20299,"39093":20338,"39094":20386,"39095":20400,"39096":20413,"39097":20424,"39098":20428,"39099":20464,"39100":20466,"39101":20473,"39102":20483,"39103":20488,"39104":20532,"39105":20539,"39106":20568,"39107":20582,"39108":20609,"39109":20624,"39110":20668,"39111":20688,"39112":20703,"39113":20705,"39114":20732,"39115":20749,"39116":20779,"39117":20832,"39118":20910,"39119":20920,"39120":20946,"39121":20962,"39122":20997,"39123":21044,"39124":21052,"39125":21081,"39126":21096,"39127":21113,"39128":21156,"39129":21196,"39130":21287,"39131":21314,"39132":21341,"39133":21373,"39134":21374,"39135":21445,"39136":21456,"39137":21458,"39138":21502,"39139":21613,"39140":21637,"39141":21651,"39142":21662,"39143":21689,"39144":21731,"39145":21743,"39146":21773,"39147":21784,"39148":21797,"39149":21800,"39150":21803,"39151":21831,"39152":21881,"39153":21904,"39154":21940,"39155":21953,"39156":21975,"39157":21976,"39158":22011,"39159":20404,"39160":22049,"39161":8707,"39162":22098,"39163":59852,"39164":9787,"39165":59854,"39166":59855,"39232":22109,"39233":9332,"39234":9333,"39235":9334,"39236":9335,"39237":9336,"39238":9337,"39239":9338,"39240":9339,"39241":9340,"39242":9341,"39243":9342,"39244":9343,"39245":9344,"39246":9345,"39247":9346,"39248":9347,"39249":9348,"39250":9349,"39251":9350,"39252":9351,"39253":22113,"39254":22153,"39255":22155,"39256":22174,"39257":22177,"39258":22193,"39259":22201,"39260":22207,"39261":22230,"39262":22255,"39263":22293,"39264":22301,"39265":22322,"39266":22333,"39267":22335,"39268":22339,"39269":8660,"39270":22398,"39271":22410,"39272":22413,"39273":22416,"39274":22428,"39275":22459,"39276":22462,"39277":22468,"39278":22494,"39279":22526,"39280":22546,"39281":22562,"39282":22599,"39283":22620,"39284":22623,"39285":22643,"39286":22695,"39287":22698,"39288":22704,"39289":22709,"39290":22710,"39291":22731,"39292":22736,"39293":22752,"39294":22789,"39329":22801,"39330":22921,"39331":22932,"39332":22938,"39333":22943,"39334":22960,"39335":22968,"39336":22980,"39337":23023,"39338":23024,"39339":23032,"39340":23042,"39341":23051,"39342":23053,"39343":23058,"39344":23073,"39345":23076,"39346":23079,"39347":23082,"39348":23083,"39349":23084,"39350":23101,"39351":23109,"39352":23124,"39353":23129,"39354":23137,"39355":23144,"39356":23147,"39357":23150,"39358":23153,"39359":23161,"39360":23166,"39361":23169,"39362":23170,"39363":23174,"39364":23176,"39365":23185,"39366":23193,"39367":23200,"39368":23201,"39369":23211,"39370":23235,"39371":23246,"39372":23247,"39373":23251,"39374":23268,"39375":23280,"39376":23294,"39377":23309,"39378":23313,"39379":23317,"39380":23327,"39381":23339,"39382":23361,"39383":23364,"39384":23366,"39385":23370,"39386":23375,"39387":23400,"39388":23412,"39389":23414,"39390":23420,"39391":23426,"39392":23440,"39393":9372,"39394":9373,"39395":9374,"39396":9375,"39397":9376,"39398":9377,"39399":9378,"39400":9379,"39401":9380,"39402":9381,"39403":9382,"39404":9383,"39405":9384,"39406":9385,"39407":9386,"39408":9387,"39409":9388,"39410":9389,"39411":9390,"39412":9391,"39413":9392,"39414":9393,"39415":9394,"39416":9395,"39417":9396,"39418":9397,"39419":60009,"39420":12850,"39421":12849,"39422":27307,"39488":23446,"39489":9352,"39490":9353,"39491":9354,"39492":9355,"39493":9356,"39494":9357,"39495":9358,"39496":9359,"39497":9360,"39498":9361,"39499":9362,"39500":9363,"39501":9364,"39502":9365,"39503":9366,"39504":9367,"39505":9368,"39506":9369,"39507":9370,"39508":9371,"39509":23509,"39510":23511,"39511":23587,"39512":23685,"39513":23710,"39514":23746,"39515":23824,"39516":23852,"39517":23855,"39518":23880,"39519":23894,"39520":23920,"39521":23931,"39522":23941,"39523":23972,"39524":23979,"39525":23990,"39526":24001,"39527":24023,"39528":24073,"39529":24136,"39530":24210,"39531":24253,"39532":24334,"39533":24434,"39534":24497,"39535":24514,"39536":24539,"39537":24543,"39538":24611,"39539":24702,"39540":24791,"39541":24839,"39542":24844,"39543":24857,"39544":24866,"39545":24912,"39546":24928,"39547":24961,"39548":24981,"39549":25017,"39550":25024,"39585":25039,"39586":25043,"39587":25050,"39588":25232,"39589":25393,"39590":8835,"39591":25399,"39592":25465,"39593":25483,"39594":25537,"39595":25570,"39596":25574,"39597":25595,"39598":25598,"39599":25607,"39600":25650,"39601":25656,"39602":25659,"39603":25690,"39604":25713,"39605":25724,"39606":25741,"39607":25775,"39608":25780,"39609":25782,"39610":25821,"39611":25829,"39612":25866,"39613":25873,"39614":25887,"39615":25951,"39616":25965,"39617":25990,"39618":26037,"39619":26046,"39620":26065,"39621":26068,"39622":26083,"39623":26111,"39624":26136,"39625":26147,"39626":26211,"39627":26219,"39628":26237,"39629":26245,"39630":26258,"39631":26266,"39632":26276,"39633":26285,"39634":26291,"39635":26294,"39636":26317,"39637":26318,"39638":26370,"39639":26380,"39640":26393,"39641":26436,"39642":26475,"39643":26511,"39644":26532,"39645":26559,"39646":26582,"39647":26583,"39648":8834,"39649":26637,"39650":26640,"39651":26651,"39652":26678,"39653":26695,"39654":26710,"39655":26756,"39656":26760,"39657":26813,"39658":26819,"39659":26821,"39660":26882,"39661":26883,"39662":26889,"39663":26904,"39664":26947,"39665":26950,"39666":26980,"39667":26983,"39668":26994,"39669":27013,"39670":27039,"39671":27042,"39672":27089,"39673":27093,"39674":27094,"39675":39457,"39676":39462,"39677":39471,"39678":27329,"39744":22975,"39745":27105,"39746":27139,"39747":27162,"39748":27164,"39749":27180,"39750":27181,"39751":27187,"39752":27203,"39753":27205,"39754":27212,"39755":27219,"39756":27223,"39757":27235,"39758":27252,"39759":27266,"39760":27274,"39761":27279,"39762":27289,"39763":27303,"39764":27313,"39765":27317,"39766":27326,"39767":27337,"39768":27348,"39769":27352,"39770":27382,"39771":27479,"39772":27514,"39773":27612,"39774":27676,"39775":27697,"39776":27736,"39777":27758,"39778":27765,"39779":27775,"39780":27823,"39781":27851,"39782":27871,"39783":27903,"39784":27906,"39785":27909,"39786":27910,"39787":27942,"39788":27991,"39789":27995,"39790":28017,"39791":28033,"39792":28047,"39793":28069,"39794":28081,"39795":28158,"39796":28162,"39797":28164,"39798":28175,"39799":28184,"39800":28202,"39801":28240,"39802":28249,"39803":28314,"39804":28341,"39805":28344,"39806":28379,"39841":28410,"39842":28420,"39843":28427,"39844":28428,"39845":28438,"39846":28439,"39847":28468,"39848":28477,"39849":28502,"39850":28537,"39851":28554,"39852":28573,"39853":28575,"39854":28603,"39855":28606,"39856":28627,"39857":28633,"39858":28664,"39859":28675,"39860":28747,"39861":28749,"39862":28752,"39863":28756,"39864":28764,"39865":28775,"39866":28791,"39867":28793,"39868":28811,"39869":28815,"39870":28832,"39871":28835,"39872":28837,"39873":28838,"39874":28839,"39875":28868,"39876":28876,"39877":28880,"39878":28886,"39879":618,"39880":603,"39881":230,"39882":652,"39883":593,"39884":596,"39885":650,"39886":605,"39887":601,"39888":602,"39889":604,"39890":609,"39891":7747,"39892":7753,"39893":330,"39894":7739,"39895":629,"39896":240,"39897":643,"39898":658,"39899":679,"39900":676,"39901":227,"39902":60294,"39903":60295,"39904":623,"39905":632,"39906":647,"39907":60299,"39908":199,"39909":339,"39910":594,"39911":65351,"39912":715,"39913":719,"39914":65345,"39915":65346,"39916":65348,"39917":65349,"39918":65350,"39919":65352,"39920":65353,"39921":65354,"39922":65355,"39923":65356,"39924":65357,"39925":65358,"39926":65359,"39927":65360,"39928":65362,"39929":65363,"39930":65364,"39931":65365,"39932":65366,"39933":65367,"39934":65370,"40000":28917,"40001":12832,"40002":12833,"40003":12834,"40004":12835,"40005":12836,"40006":12837,"40007":12838,"40008":12839,"40009":12840,"40010":12841,"40011":28926,"40012":28933,"40013":28957,"40014":28969,"40015":28971,"40016":28972,"40017":28979,"40018":28981,"40019":28987,"40020":28990,"40021":28992,"40022":29007,"40023":29035,"40024":29045,"40025":29047,"40026":29052,"40027":29054,"40028":29068,"40029":29070,"40030":29073,"40031":29078,"40032":29090,"40033":29091,"40034":29101,"40035":29108,"40036":29111,"40037":29114,"40038":29137,"40039":29149,"40040":29163,"40041":29184,"40042":29193,"40043":29198,"40044":29199,"40045":29206,"40046":29207,"40047":29220,"40048":23204,"40049":29230,"40050":8838,"40051":29271,"40052":29276,"40053":29332,"40054":29444,"40055":29456,"40056":29505,"40057":29556,"40058":29580,"40059":29583,"40060":29592,"40061":29596,"40062":29598,"40097":29607,"40098":29610,"40099":29653,"40100":29665,"40101":29666,"40102":29668,"40103":29670,"40104":29679,"40105":29683,"40106":8839,"40107":29689,"40108":29691,"40109":29698,"40110":29713,"40111":29714,"40112":29716,"40113":29717,"40114":29719,"40115":29721,"40116":29724,"40117":29726,"40118":29727,"40119":29751,"40120":29752,"40121":29753,"40122":29763,"40123":29765,"40124":29767,"40125":29768,"40126":29769,"40127":29779,"40128":29782,"40129":29797,"40130":29803,"40131":29804,"40132":29812,"40133":29818,"40134":29826,"40135":21378,"40136":24191,"40137":20008,"40138":24186,"40139":20886,"40140":23424,"40141":21353,"40142":11911,"40143":60436,"40144":21251,"40145":9746,"40146":33401,"40147":17553,"40148":11916,"40149":11914,"40150":20022,"40151":60444,"40152":21274,"40153":60446,"40154":60447,"40155":11925,"40156":60449,"40157":60450,"40158":9492,"40159":20058,"40160":36790,"40161":24308,"40162":20872,"40163":20101,"40164":60457,"40165":20031,"40166":60459,"40167":60460,"40168":20059,"40169":21430,"40170":36710,"40171":32415,"40172":35744,"40173":36125,"40174":40479,"40175":38376,"40176":38021,"40177":38429,"40178":25164,"40179":27701,"40180":20155,"40181":24516,"40182":28780,"40183":11950,"40184":21475,"40185":27362,"40186":39483,"40187":39484,"40188":39512,"40189":39516,"40190":39523,"40256":9742,"40257":8594,"40258":8592,"40259":8593,"40260":8595,"40261":8680,"40262":8678,"40263":8679,"40264":8681,"40265":8680,"40266":8678,"40267":8679,"40268":8681,"40269":9758,"40270":9756,"40271":9755,"40272":9759,"40273":12310,"40274":12311,"40275":9675,"40276":10005,"40277":10003,"40278":22267,"40279":9789,"40280":22813,"40281":26189,"40282":29221,"40283":10025,"40284":10017,"40285":9786,"40286":9785,"40287":60515,"40288":60516,"40289":60517,"40290":60518,"40291":60519,"40292":23672,"40293":9836,"40294":9834,"40295":23249,"40296":23479,"40297":23804,"40298":60526,"40299":9993,"40300":9986,"40301":60529,"40302":60530,"40303":60531,"40304":60532,"40305":23765,"40306":26478,"40307":29793,"40308":29853,"40309":32595,"40310":34195,"40311":10063,"40312":60540,"40313":60541,"40314":23928,"40315":24379,"40316":60544,"40317":9473,"40318":9475,"40353":60547,"40354":60548,"40355":60549,"40356":60550,"40357":60551,"40358":60552,"40359":60553,"40360":60554,"40361":60555,"40362":60556,"40363":60557,"40364":60558,"40365":60559,"40366":60560,"40367":60561,"40368":39602,"40369":39648,"40370":39700,"40371":39732,"40372":39737,"40373":39744,"40374":39760,"40375":39807,"40376":9788,"40377":32149,"40378":9729,"40379":38708,"40380":9730,"40381":60575,"40382":60576,"40383":60577,"40384":9992,"40385":60579,"40386":60580,"40387":60581,"40388":60582,"40389":60583,"40390":60584,"40391":60585,"40392":8507,"40393":8481,"40394":26343,"40395":28247,"40396":60590,"40397":29015,"40398":31178,"40399":8470,"40400":33132,"40401":35577,"40402":38998,"40403":60597,"40404":60598,"40405":9760,"40406":60600,"40407":9828,"40408":9824,"40409":9831,"40410":9827,"40411":9826,"40412":9830,"40413":9825,"40414":9829,"40415":60609,"40416":60610,"40417":27364,"40418":8478,"40419":13250,"40420":13272,"40421":13217,"40422":60616,"40423":13221,"40424":60618,"40425":60619,"40426":60620,"40427":60621,"40428":60622,"40429":9745,"40430":39809,"40431":39819,"40432":39821,"40433":39901,"40434":39913,"40435":39917,"40436":39924,"40437":39967,"40438":39968,"40439":39974,"40440":40019,"40441":40029,"40442":40059,"40443":40204,"40444":40214,"40445":8626,"40446":27397,"40512":36073,"40513":36082,"40514":36099,"40515":36113,"40516":36124,"40517":36218,"40518":36265,"40519":36288,"40520":36353,"40521":36366,"40522":36422,"40523":36456,"40524":36465,"40525":36478,"40526":36480,"40527":36534,"40528":36537,"40529":36540,"40530":36547,"40531":36580,"40532":36589,"40533":36594,"40534":36656,"40535":36673,"40536":36682,"40537":36773,"40538":36787,"40539":36792,"40540":36810,"40541":36815,"40542":36872,"40543":36915,"40544":36919,"40545":36964,"40546":36972,"40547":37289,"40548":37302,"40549":37316,"40550":37370,"40551":37384,"40552":37395,"40553":37409,"40554":37416,"40555":37419,"40556":37429,"40557":37436,"40558":37441,"40559":37464,"40560":37469,"40561":37471,"40562":37483,"40563":37486,"40564":37505,"40565":37508,"40566":37513,"40567":37519,"40568":37553,"40569":37562,"40570":37567,"40571":37588,"40572":37595,"40573":37603,"40574":37605,"40609":37611,"40610":37612,"40611":37620,"40612":37622,"40613":37629,"40614":37635,"40615":37639,"40616":37680,"40617":37681,"40618":37696,"40619":37698,"40620":37699,"40621":37727,"40622":37730,"40623":37734,"40624":37736,"40625":37747,"40626":37748,"40627":37752,"40628":37757,"40629":37761,"40630":37764,"40631":37766,"40632":37767,"40633":37776,"40634":37788,"40635":37792,"40636":37816,"40637":37819,"40638":37821,"40639":37823,"40640":37835,"40641":37843,"40642":37851,"40643":37856,"40644":37872,"40645":37873,"40646":37875,"40647":37876,"40648":37889,"40649":37892,"40650":37896,"40651":37911,"40652":37915,"40653":37917,"40654":37924,"40655":37925,"40656":37926,"40657":37933,"40658":37954,"40659":37955,"40660":37965,"40661":37972,"40662":37976,"40663":37989,"40664":37991,"40665":37996,"40666":38009,"40667":38011,"40668":38264,"40669":38277,"40670":38310,"40671":38314,"40672":38486,"40673":38523,"40674":38565,"40675":38644,"40676":38683,"40677":38710,"40678":38720,"40679":38721,"40680":38743,"40681":38791,"40682":38793,"40683":38811,"40684":38833,"40685":38845,"40686":38848,"40687":38850,"40688":38866,"40689":38880,"40690":38932,"40691":38933,"40692":38947,"40693":38963,"40694":39016,"40695":39095,"40696":39097,"40697":39111,"40698":39114,"40699":39136,"40700":39137,"40701":39148,"40702":39157,"40768":40225,"40769":40244,"40770":40249,"40771":40265,"40772":40270,"40773":40301,"40774":8759,"40775":40302,"40776":40316,"40777":40323,"40778":40339,"40779":40357,"40780":8748,"40781":40381,"40782":27521,"40783":27569,"40784":40015,"40785":40592,"40786":40384,"40787":60817,"40788":60818,"40789":9775,"40790":9776,"40791":9783,"40792":9779,"40793":9780,"40794":9781,"40795":9778,"40796":9782,"40797":9777,"40798":40393,"40799":40404,"40800":40444,"40801":40458,"40802":40460,"40803":40462,"40804":40472,"40805":40571,"40806":40581,"40807":40610,"40808":40620,"40809":40625,"40810":40641,"40811":40646,"40812":40647,"40813":40689,"40814":40696,"40815":40743,"40816":39182,"40817":39193,"40818":39196,"40819":39223,"40820":39261,"40821":39266,"40822":39323,"40823":39332,"40824":39338,"40825":39352,"40826":39392,"40827":39398,"40828":39413,"40829":39455,"40830":32254,"40865":32263,"40866":32347,"40867":32357,"40868":32364,"40869":32567,"40870":32576,"40871":32577,"40872":32585,"40873":32594,"40874":32655,"40875":32659,"40876":32692,"40877":32733,"40878":32743,"40879":32762,"40880":32770,"40881":32776,"40882":32814,"40883":32815,"40884":32828,"40885":32935,"40886":33036,"40887":33066,"40888":33076,"40889":33090,"40890":33110,"40891":33156,"40892":33189,"40893":33252,"40894":33364,"40895":33381,"40896":33403,"40897":33415,"40898":33471,"40899":33506,"40900":33518,"40901":33528,"40902":33532,"40903":33535,"40904":33547,"40905":33565,"40906":33597,"40907":33623,"40908":33681,"40909":33708,"40910":33741,"40911":33773,"40912":33797,"40913":33812,"40914":33814,"40915":33825,"40916":33838,"40917":33854,"40918":33866,"40919":33875,"40920":33877,"40921":33880,"40922":33892,"40923":33906,"40924":33919,"40925":33920,"40926":33938,"40927":33939,"40928":33942,"40929":33955,"40930":33982,"40931":34014,"40932":34017,"40933":34018,"40934":34020,"40935":34040,"40936":34051,"40937":34053,"40938":34064,"40939":34099,"40940":8208,"40941":34114,"40942":34124,"40943":34130,"40944":34143,"40945":34159,"40946":34160,"40947":34163,"40948":34262,"40949":34272,"40950":34286,"40951":34300,"40952":34317,"40953":34319,"40954":34324,"40955":34344,"40956":34370,"40957":34373,"40958":34418,"41024":34972,"41025":23405,"41026":33079,"41027":60958,"41028":39224,"41029":21874,"41030":21867,"41031":60962,"41032":13774,"41033":21873,"41034":21946,"41035":22001,"41036":13778,"41037":22000,"41038":22021,"41039":22050,"41040":22061,"41041":22083,"41042":22046,"41043":22162,"41044":31949,"41045":21530,"41046":21523,"41047":21655,"41048":26353,"41049":30004,"41050":21581,"41051":22180,"41052":22175,"41053":25811,"41054":25390,"41055":25592,"41056":25886,"41057":20088,"41058":27626,"41059":27698,"41060":27709,"41061":27746,"41062":27826,"41063":28152,"41064":28201,"41065":28278,"41066":28290,"41067":28294,"41068":28347,"41069":28383,"41070":28386,"41071":28433,"41072":28452,"41073":28532,"41074":28561,"41075":28597,"41076":28659,"41077":28661,"41078":28859,"41079":28864,"41080":28943,"41081":8706,"41082":29013,"41083":29043,"41084":29050,"41085":61016,"41086":21027,"41121":61018,"41122":13393,"41123":61020,"41124":36812,"41125":61022,"41126":61023,"41127":192,"41128":200,"41129":204,"41130":210,"41131":217,"41132":193,"41133":205,"41134":211,"41135":218,"41136":257,"41137":275,"41138":299,"41139":333,"41140":363,"41141":470,"41142":196,"41143":203,"41144":207,"41145":214,"41146":220,"41147":198,"41148":199,"41149":209,"41150":195,"41151":213,"41152":225,"41153":233,"41154":237,"41155":243,"41156":250,"41157":472,"41158":228,"41159":235,"41160":239,"41161":246,"41162":252,"41163":230,"41164":231,"41165":241,"41166":227,"41167":245,"41168":462,"41169":283,"41170":464,"41171":466,"41172":468,"41173":474,"41174":197,"41175":201,"41176":29064,"41177":216,"41178":208,"41179":7922,"41180":222,"41181":223,"41182":170,"41183":161,"41184":224,"41185":232,"41186":236,"41187":242,"41188":249,"41189":476,"41190":229,"41191":29080,"41192":29143,"41193":248,"41194":240,"41195":7923,"41196":254,"41197":255,"41198":186,"41199":191,"41200":226,"41201":234,"41202":238,"41203":244,"41204":251,"41205":29173,"41206":194,"41207":202,"41208":206,"41209":212,"41210":219,"41211":184,"41212":164,"41213":61110,"41214":402,"41280":12288,"41281":65292,"41282":12289,"41283":12290,"41284":65294,"41285":8231,"41286":65307,"41287":65306,"41288":65311,"41289":65281,"41290":65072,"41291":8230,"41292":8229,"41293":65104,"41294":65105,"41295":65106,"41296":183,"41297":65108,"41298":65109,"41299":65110,"41300":65111,"41301":65372,"41302":8211,"41303":65073,"41304":8212,"41305":65075,"41306":9588,"41307":65076,"41308":65103,"41309":65288,"41310":65289,"41311":65077,"41312":65078,"41313":65371,"41314":65373,"41315":65079,"41316":65080,"41317":12308,"41318":12309,"41319":65081,"41320":65082,"41321":12304,"41322":12305,"41323":65083,"41324":65084,"41325":12298,"41326":12299,"41327":65085,"41328":65086,"41329":12296,"41330":12297,"41331":65087,"41332":65088,"41333":12300,"41334":12301,"41335":65089,"41336":65090,"41337":12302,"41338":12303,"41339":65091,"41340":65092,"41341":65113,"41342":65114,"41377":65115,"41378":65116,"41379":65117,"41380":65118,"41381":8216,"41382":8217,"41383":8220,"41384":8221,"41385":12317,"41386":12318,"41387":8245,"41388":8242,"41389":65283,"41390":65286,"41391":65290,"41392":8251,"41393":167,"41394":12291,"41395":9675,"41396":9679,"41397":9651,"41398":9650,"41399":9678,"41400":9734,"41401":9733,"41402":9671,"41403":9670,"41404":9633,"41405":9632,"41406":9661,"41407":9660,"41408":12963,"41409":8453,"41410":175,"41411":65507,"41412":65343,"41413":717,"41414":65097,"41415":65098,"41416":65101,"41417":65102,"41418":65099,"41419":65100,"41420":65119,"41421":65120,"41422":65121,"41423":65291,"41424":65293,"41425":215,"41426":247,"41427":177,"41428":8730,"41429":65308,"41430":65310,"41431":65309,"41432":8806,"41433":8807,"41434":8800,"41435":8734,"41436":8786,"41437":8801,"41438":65122,"41439":65123,"41440":65124,"41441":65125,"41442":65126,"41443":65374,"41444":8745,"41445":8746,"41446":8869,"41447":8736,"41448":8735,"41449":8895,"41450":13266,"41451":13265,"41452":8747,"41453":8750,"41454":8757,"41455":8756,"41456":9792,"41457":9794,"41458":8853,"41459":8857,"41460":8593,"41461":8595,"41462":8592,"41463":8594,"41464":8598,"41465":8599,"41466":8601,"41467":8600,"41468":8741,"41469":8739,"41470":65295,"41536":65340,"41537":8725,"41538":65128,"41539":65284,"41540":65509,"41541":12306,"41542":65504,"41543":65505,"41544":65285,"41545":65312,"41546":8451,"41547":8457,"41548":65129,"41549":65130,"41550":65131,"41551":13269,"41552":13212,"41553":13213,"41554":13214,"41555":13262,"41556":13217,"41557":13198,"41558":13199,"41559":13252,"41560":176,"41561":20825,"41562":20827,"41563":20830,"41564":20829,"41565":20833,"41566":20835,"41567":21991,"41568":29929,"41569":31950,"41570":9601,"41571":9602,"41572":9603,"41573":9604,"41574":9605,"41575":9606,"41576":9607,"41577":9608,"41578":9615,"41579":9614,"41580":9613,"41581":9612,"41582":9611,"41583":9610,"41584":9609,"41585":9532,"41586":9524,"41587":9516,"41588":9508,"41589":9500,"41590":9620,"41591":9472,"41592":9474,"41593":9621,"41594":9484,"41595":9488,"41596":9492,"41597":9496,"41598":9581,"41633":9582,"41634":9584,"41635":9583,"41636":9552,"41637":9566,"41638":9578,"41639":9569,"41640":9698,"41641":9699,"41642":9701,"41643":9700,"41644":9585,"41645":9586,"41646":9587,"41647":65296,"41648":65297,"41649":65298,"41650":65299,"41651":65300,"41652":65301,"41653":65302,"41654":65303,"41655":65304,"41656":65305,"41657":8544,"41658":8545,"41659":8546,"41660":8547,"41661":8548,"41662":8549,"41663":8550,"41664":8551,"41665":8552,"41666":8553,"41667":12321,"41668":12322,"41669":12323,"41670":12324,"41671":12325,"41672":12326,"41673":12327,"41674":12328,"41675":12329,"41676":21313,"41677":21316,"41678":21317,"41679":65313,"41680":65314,"41681":65315,"41682":65316,"41683":65317,"41684":65318,"41685":65319,"41686":65320,"41687":65321,"41688":65322,"41689":65323,"41690":65324,"41691":65325,"41692":65326,"41693":65327,"41694":65328,"41695":65329,"41696":65330,"41697":65331,"41698":65332,"41699":65333,"41700":65334,"41701":65335,"41702":65336,"41703":65337,"41704":65338,"41705":65345,"41706":65346,"41707":65347,"41708":65348,"41709":65349,"41710":65350,"41711":65351,"41712":65352,"41713":65353,"41714":65354,"41715":65355,"41716":65356,"41717":65357,"41718":65358,"41719":65359,"41720":65360,"41721":65361,"41722":65362,"41723":65363,"41724":65364,"41725":65365,"41726":65366,"41792":65367,"41793":65368,"41794":65369,"41795":65370,"41796":913,"41797":914,"41798":915,"41799":916,"41800":917,"41801":918,"41802":919,"41803":920,"41804":921,"41805":922,"41806":923,"41807":924,"41808":925,"41809":926,"41810":927,"41811":928,"41812":929,"41813":931,"41814":932,"41815":933,"41816":934,"41817":935,"41818":936,"41819":937,"41820":945,"41821":946,"41822":947,"41823":948,"41824":949,"41825":950,"41826":951,"41827":952,"41828":953,"41829":954,"41830":955,"41831":956,"41832":957,"41833":958,"41834":959,"41835":960,"41836":961,"41837":963,"41838":964,"41839":965,"41840":966,"41841":967,"41842":968,"41843":969,"41844":12549,"41845":12550,"41846":12551,"41847":12552,"41848":12553,"41849":12554,"41850":12555,"41851":12556,"41852":12557,"41853":12558,"41854":12559,"41889":12560,"41890":12561,"41891":12562,"41892":12563,"41893":12564,"41894":12565,"41895":12566,"41896":12567,"41897":12568,"41898":12569,"41899":12570,"41900":12571,"41901":12572,"41902":12573,"41903":12574,"41904":12575,"41905":12576,"41906":12577,"41907":12578,"41908":12579,"41909":12580,"41910":12581,"41911":12582,"41912":12583,"41913":12584,"41914":12585,"41915":729,"41916":713,"41917":714,"41918":711,"41919":715,"41920":9216,"41921":9217,"41922":9218,"41923":9219,"41924":9220,"41925":9221,"41926":9222,"41927":9223,"41928":9224,"41929":9225,"41930":9226,"41931":9227,"41932":9228,"41933":9229,"41934":9230,"41935":9231,"41936":9232,"41937":9233,"41938":9234,"41939":9235,"41940":9236,"41941":9237,"41942":9238,"41943":9239,"41944":9240,"41945":9241,"41946":9242,"41947":9243,"41948":9244,"41949":9245,"41950":9246,"41951":9247,"41952":9249,"41953":8364,"41954":63561,"41955":63562,"41956":63563,"41957":63564,"41958":63565,"41959":63566,"41960":63567,"41961":63568,"41962":63569,"41963":63570,"41964":63571,"41965":63572,"41966":63573,"41967":63574,"41968":63575,"41969":63576,"41970":63577,"41971":63578,"41972":63579,"41973":63580,"41974":63581,"41975":63582,"41976":63583,"41977":63584,"41978":63585,"41979":63586,"41980":63587,"41981":63588,"41982":63589,"42048":19968,"42049":20057,"42050":19969,"42051":19971,"42052":20035,"42053":20061,"42054":20102,"42055":20108,"42056":20154,"42057":20799,"42058":20837,"42059":20843,"42060":20960,"42061":20992,"42062":20993,"42063":21147,"42064":21269,"42065":21313,"42066":21340,"42067":21448,"42068":19977,"42069":19979,"42070":19976,"42071":19978,"42072":20011,"42073":20024,"42074":20961,"42075":20037,"42076":20040,"42077":20063,"42078":20062,"42079":20110,"42080":20129,"42081":20800,"42082":20995,"42083":21242,"42084":21315,"42085":21449,"42086":21475,"42087":22303,"42088":22763,"42089":22805,"42090":22823,"42091":22899,"42092":23376,"42093":23377,"42094":23379,"42095":23544,"42096":23567,"42097":23586,"42098":23608,"42099":23665,"42100":24029,"42101":24037,"42102":24049,"42103":24050,"42104":24051,"42105":24062,"42106":24178,"42107":24318,"42108":24331,"42109":24339,"42110":25165,"42145":19985,"42146":19984,"42147":19981,"42148":20013,"42149":20016,"42150":20025,"42151":20043,"42152":23609,"42153":20104,"42154":20113,"42155":20117,"42156":20114,"42157":20116,"42158":20130,"42159":20161,"42160":20160,"42161":20163,"42162":20166,"42163":20167,"42164":20173,"42165":20170,"42166":20171,"42167":20164,"42168":20803,"42169":20801,"42170":20839,"42171":20845,"42172":20846,"42173":20844,"42174":20887,"42175":20982,"42176":20998,"42177":20999,"42178":21000,"42179":21243,"42180":21246,"42181":21247,"42182":21270,"42183":21305,"42184":21320,"42185":21319,"42186":21317,"42187":21342,"42188":21380,"42189":21451,"42190":21450,"42191":21453,"42192":22764,"42193":22825,"42194":22827,"42195":22826,"42196":22829,"42197":23380,"42198":23569,"42199":23588,"42200":23610,"42201":23663,"42202":24052,"42203":24187,"42204":24319,"42205":24340,"42206":24341,"42207":24515,"42208":25096,"42209":25142,"42210":25163,"42211":25166,"42212":25903,"42213":25991,"42214":26007,"42215":26020,"42216":26041,"42217":26085,"42218":26352,"42219":26376,"42220":26408,"42221":27424,"42222":27490,"42223":27513,"42224":27595,"42225":27604,"42226":27611,"42227":27663,"42228":27700,"42229":28779,"42230":29226,"42231":29238,"42232":29243,"42233":29255,"42234":29273,"42235":29275,"42236":29356,"42237":29579,"42238":19993,"42304":19990,"42305":19989,"42306":19988,"42307":19992,"42308":20027,"42309":20045,"42310":20047,"42311":20046,"42312":20197,"42313":20184,"42314":20180,"42315":20181,"42316":20182,"42317":20183,"42318":20195,"42319":20196,"42320":20185,"42321":20190,"42322":20805,"42323":20804,"42324":20873,"42325":20874,"42326":20908,"42327":20985,"42328":20986,"42329":20984,"42330":21002,"42331":21152,"42332":21151,"42333":21253,"42334":21254,"42335":21271,"42336":21277,"42337":20191,"42338":21322,"42339":21321,"42340":21345,"42341":21344,"42342":21359,"42343":21358,"42344":21435,"42345":21487,"42346":21476,"42347":21491,"42348":21484,"42349":21486,"42350":21481,"42351":21480,"42352":21500,"42353":21496,"42354":21493,"42355":21483,"42356":21478,"42357":21482,"42358":21490,"42359":21489,"42360":21488,"42361":21477,"42362":21485,"42363":21499,"42364":22235,"42365":22234,"42366":22806,"42401":22830,"42402":22833,"42403":22900,"42404":22902,"42405":23381,"42406":23427,"42407":23612,"42408":24040,"42409":24039,"42410":24038,"42411":24066,"42412":24067,"42413":24179,"42414":24188,"42415":24321,"42416":24344,"42417":24343,"42418":24517,"42419":25098,"42420":25171,"42421":25172,"42422":25170,"42423":25169,"42424":26021,"42425":26086,"42426":26414,"42427":26412,"42428":26410,"42429":26411,"42430":26413,"42431":27491,"42432":27597,"42433":27665,"42434":27664,"42435":27704,"42436":27713,"42437":27712,"42438":27710,"42439":29359,"42440":29572,"42441":29577,"42442":29916,"42443":29926,"42444":29976,"42445":29983,"42446":29992,"42447":29993,"42448":30000,"42449":30001,"42450":30002,"42451":30003,"42452":30091,"42453":30333,"42454":30382,"42455":30399,"42456":30446,"42457":30683,"42458":30690,"42459":30707,"42460":31034,"42461":31166,"42462":31348,"42463":31435,"42464":19998,"42465":19999,"42466":20050,"42467":20051,"42468":20073,"42469":20121,"42470":20132,"42471":20134,"42472":20133,"42473":20223,"42474":20233,"42475":20249,"42476":20234,"42477":20245,"42478":20237,"42479":20240,"42480":20241,"42481":20239,"42482":20210,"42483":20214,"42484":20219,"42485":20208,"42486":20211,"42487":20221,"42488":20225,"42489":20235,"42490":20809,"42491":20807,"42492":20806,"42493":20808,"42494":20840,"42560":20849,"42561":20877,"42562":20912,"42563":21015,"42564":21009,"42565":21010,"42566":21006,"42567":21014,"42568":21155,"42569":21256,"42570":21281,"42571":21280,"42572":21360,"42573":21361,"42574":21513,"42575":21519,"42576":21516,"42577":21514,"42578":21520,"42579":21505,"42580":21515,"42581":21508,"42582":21521,"42583":21517,"42584":21512,"42585":21507,"42586":21518,"42587":21510,"42588":21522,"42589":22240,"42590":22238,"42591":22237,"42592":22323,"42593":22320,"42594":22312,"42595":22317,"42596":22316,"42597":22319,"42598":22313,"42599":22809,"42600":22810,"42601":22839,"42602":22840,"42603":22916,"42604":22904,"42605":22915,"42606":22909,"42607":22905,"42608":22914,"42609":22913,"42610":23383,"42611":23384,"42612":23431,"42613":23432,"42614":23429,"42615":23433,"42616":23546,"42617":23574,"42618":23673,"42619":24030,"42620":24070,"42621":24182,"42622":24180,"42657":24335,"42658":24347,"42659":24537,"42660":24534,"42661":25102,"42662":25100,"42663":25101,"42664":25104,"42665":25187,"42666":25179,"42667":25176,"42668":25910,"42669":26089,"42670":26088,"42671":26092,"42672":26093,"42673":26354,"42674":26355,"42675":26377,"42676":26429,"42677":26420,"42678":26417,"42679":26421,"42680":27425,"42681":27492,"42682":27515,"42683":27670,"42684":27741,"42685":27735,"42686":27737,"42687":27743,"42688":27744,"42689":27728,"42690":27733,"42691":27745,"42692":27739,"42693":27725,"42694":27726,"42695":28784,"42696":29279,"42697":29277,"42698":30334,"42699":31481,"42700":31859,"42701":31992,"42702":32566,"42703":32650,"42704":32701,"42705":32769,"42706":32771,"42707":32780,"42708":32786,"42709":32819,"42710":32895,"42711":32905,"42712":32907,"42713":32908,"42714":33251,"42715":33258,"42716":33267,"42717":33276,"42718":33292,"42719":33307,"42720":33311,"42721":33390,"42722":33394,"42723":33406,"42724":34411,"42725":34880,"42726":34892,"42727":34915,"42728":35199,"42729":38433,"42730":20018,"42731":20136,"42732":20301,"42733":20303,"42734":20295,"42735":20311,"42736":20318,"42737":20276,"42738":20315,"42739":20309,"42740":20272,"42741":20304,"42742":20305,"42743":20285,"42744":20282,"42745":20280,"42746":20291,"42747":20308,"42748":20284,"42749":20294,"42750":20323,"42816":20316,"42817":20320,"42818":20271,"42819":20302,"42820":20278,"42821":20313,"42822":20317,"42823":20296,"42824":20314,"42825":20812,"42826":20811,"42827":20813,"42828":20853,"42829":20918,"42830":20919,"42831":21029,"42832":21028,"42833":21033,"42834":21034,"42835":21032,"42836":21163,"42837":21161,"42838":21162,"42839":21164,"42840":21283,"42841":21363,"42842":21365,"42843":21533,"42844":21549,"42845":21534,"42846":21566,"42847":21542,"42848":21582,"42849":21543,"42850":21574,"42851":21571,"42852":21555,"42853":21576,"42854":21570,"42855":21531,"42856":21545,"42857":21578,"42858":21561,"42859":21563,"42860":21560,"42861":21550,"42862":21557,"42863":21558,"42864":21536,"42865":21564,"42866":21568,"42867":21553,"42868":21547,"42869":21535,"42870":21548,"42871":22250,"42872":22256,"42873":22244,"42874":22251,"42875":22346,"42876":22353,"42877":22336,"42878":22349,"42913":22343,"42914":22350,"42915":22334,"42916":22352,"42917":22351,"42918":22331,"42919":22767,"42920":22846,"42921":22941,"42922":22930,"42923":22952,"42924":22942,"42925":22947,"42926":22937,"42927":22934,"42928":22925,"42929":22948,"42930":22931,"42931":22922,"42932":22949,"42933":23389,"42934":23388,"42935":23386,"42936":23387,"42937":23436,"42938":23435,"42939":23439,"42940":23596,"42941":23616,"42942":23617,"42943":23615,"42944":23614,"42945":23696,"42946":23697,"42947":23700,"42948":23692,"42949":24043,"42950":24076,"42951":24207,"42952":24199,"42953":24202,"42954":24311,"42955":24324,"42956":24351,"42957":24420,"42958":24418,"42959":24439,"42960":24441,"42961":24536,"42962":24524,"42963":24535,"42964":24525,"42965":24561,"42966":24555,"42967":24568,"42968":24554,"42969":25106,"42970":25105,"42971":25220,"42972":25239,"42973":25238,"42974":25216,"42975":25206,"42976":25225,"42977":25197,"42978":25226,"42979":25212,"42980":25214,"42981":25209,"42982":25203,"42983":25234,"42984":25199,"42985":25240,"42986":25198,"42987":25237,"42988":25235,"42989":25233,"42990":25222,"42991":25913,"42992":25915,"42993":25912,"42994":26097,"42995":26356,"42996":26463,"42997":26446,"42998":26447,"42999":26448,"43000":26449,"43001":26460,"43002":26454,"43003":26462,"43004":26441,"43005":26438,"43006":26464,"43072":26451,"43073":26455,"43074":27493,"43075":27599,"43076":27714,"43077":27742,"43078":27801,"43079":27777,"43080":27784,"43081":27785,"43082":27781,"43083":27803,"43084":27754,"43085":27770,"43086":27792,"43087":27760,"43088":27788,"43089":27752,"43090":27798,"43091":27794,"43092":27773,"43093":27779,"43094":27762,"43095":27774,"43096":27764,"43097":27782,"43098":27766,"43099":27789,"43100":27796,"43101":27800,"43102":27778,"43103":28790,"43104":28796,"43105":28797,"43106":28792,"43107":29282,"43108":29281,"43109":29280,"43110":29380,"43111":29378,"43112":29590,"43113":29996,"43114":29995,"43115":30007,"43116":30008,"43117":30338,"43118":30447,"43119":30691,"43120":31169,"43121":31168,"43122":31167,"43123":31350,"43124":31995,"43125":32597,"43126":32918,"43127":32915,"43128":32925,"43129":32920,"43130":32923,"43131":32922,"43132":32946,"43133":33391,"43134":33426,"43169":33419,"43170":33421,"43171":35211,"43172":35282,"43173":35328,"43174":35895,"43175":35910,"43176":35925,"43177":35997,"43178":36196,"43179":36208,"43180":36275,"43181":36523,"43182":36554,"43183":36763,"43184":36784,"43185":36802,"43186":36806,"43187":36805,"43188":36804,"43189":24033,"43190":37009,"43191":37026,"43192":37034,"43193":37030,"43194":37027,"43195":37193,"43196":37318,"43197":37324,"43198":38450,"43199":38446,"43200":38449,"43201":38442,"43202":38444,"43203":20006,"43204":20054,"43205":20083,"43206":20107,"43207":20123,"43208":20126,"43209":20139,"43210":20140,"43211":20335,"43212":20381,"43213":20365,"43214":20339,"43215":20351,"43216":20332,"43217":20379,"43218":20363,"43219":20358,"43220":20355,"43221":20336,"43222":20341,"43223":20360,"43224":20329,"43225":20347,"43226":20374,"43227":20350,"43228":20367,"43229":20369,"43230":20346,"43231":20820,"43232":20818,"43233":20821,"43234":20841,"43235":20855,"43236":20854,"43237":20856,"43238":20925,"43239":20989,"43240":21051,"43241":21048,"43242":21047,"43243":21050,"43244":21040,"43245":21038,"43246":21046,"43247":21057,"43248":21182,"43249":21179,"43250":21330,"43251":21332,"43252":21331,"43253":21329,"43254":21350,"43255":21367,"43256":21368,"43257":21369,"43258":21462,"43259":21460,"43260":21463,"43261":21619,"43262":21621,"43328":21654,"43329":21624,"43330":21653,"43331":21632,"43332":21627,"43333":21623,"43334":21636,"43335":21650,"43336":21638,"43337":21628,"43338":21648,"43339":21617,"43340":21622,"43341":21644,"43342":21658,"43343":21602,"43344":21608,"43345":21643,"43346":21629,"43347":21646,"43348":22266,"43349":22403,"43350":22391,"43351":22378,"43352":22377,"43353":22369,"43354":22374,"43355":22372,"43356":22396,"43357":22812,"43358":22857,"43359":22855,"43360":22856,"43361":22852,"43362":22868,"43363":22974,"43364":22971,"43365":22996,"43366":22969,"43367":22958,"43368":22993,"43369":22982,"43370":22992,"43371":22989,"43372":22987,"43373":22995,"43374":22986,"43375":22959,"43376":22963,"43377":22994,"43378":22981,"43379":23391,"43380":23396,"43381":23395,"43382":23447,"43383":23450,"43384":23448,"43385":23452,"43386":23449,"43387":23451,"43388":23578,"43389":23624,"43390":23621,"43425":23622,"43426":23735,"43427":23713,"43428":23736,"43429":23721,"43430":23723,"43431":23729,"43432":23731,"43433":24088,"43434":24090,"43435":24086,"43436":24085,"43437":24091,"43438":24081,"43439":24184,"43440":24218,"43441":24215,"43442":24220,"43443":24213,"43444":24214,"43445":24310,"43446":24358,"43447":24359,"43448":24361,"43449":24448,"43450":24449,"43451":24447,"43452":24444,"43453":24541,"43454":24544,"43455":24573,"43456":24565,"43457":24575,"43458":24591,"43459":24596,"43460":24623,"43461":24629,"43462":24598,"43463":24618,"43464":24597,"43465":24609,"43466":24615,"43467":24617,"43468":24619,"43469":24603,"43470":25110,"43471":25109,"43472":25151,"43473":25150,"43474":25152,"43475":25215,"43476":25289,"43477":25292,"43478":25284,"43479":25279,"43480":25282,"43481":25273,"43482":25298,"43483":25307,"43484":25259,"43485":25299,"43486":25300,"43487":25291,"43488":25288,"43489":25256,"43490":25277,"43491":25276,"43492":25296,"43493":25305,"43494":25287,"43495":25293,"43496":25269,"43497":25306,"43498":25265,"43499":25304,"43500":25302,"43501":25303,"43502":25286,"43503":25260,"43504":25294,"43505":25918,"43506":26023,"43507":26044,"43508":26106,"43509":26132,"43510":26131,"43511":26124,"43512":26118,"43513":26114,"43514":26126,"43515":26112,"43516":26127,"43517":26133,"43518":26122,"43584":26119,"43585":26381,"43586":26379,"43587":26477,"43588":26507,"43589":26517,"43590":26481,"43591":26524,"43592":26483,"43593":26487,"43594":26503,"43595":26525,"43596":26519,"43597":26479,"43598":26480,"43599":26495,"43600":26505,"43601":26494,"43602":26512,"43603":26485,"43604":26522,"43605":26515,"43606":26492,"43607":26474,"43608":26482,"43609":27427,"43610":27494,"43611":27495,"43612":27519,"43613":27667,"43614":27675,"43615":27875,"43616":27880,"43617":27891,"43618":27825,"43619":27852,"43620":27877,"43621":27827,"43622":27837,"43623":27838,"43624":27836,"43625":27874,"43626":27819,"43627":27861,"43628":27859,"43629":27832,"43630":27844,"43631":27833,"43632":27841,"43633":27822,"43634":27863,"43635":27845,"43636":27889,"43637":27839,"43638":27835,"43639":27873,"43640":27867,"43641":27850,"43642":27820,"43643":27887,"43644":27868,"43645":27862,"43646":27872,"43681":28821,"43682":28814,"43683":28818,"43684":28810,"43685":28825,"43686":29228,"43687":29229,"43688":29240,"43689":29256,"43690":29287,"43691":29289,"43692":29376,"43693":29390,"43694":29401,"43695":29399,"43696":29392,"43697":29609,"43698":29608,"43699":29599,"43700":29611,"43701":29605,"43702":30013,"43703":30109,"43704":30105,"43705":30106,"43706":30340,"43707":30402,"43708":30450,"43709":30452,"43710":30693,"43711":30717,"43712":31038,"43713":31040,"43714":31041,"43715":31177,"43716":31176,"43717":31354,"43718":31353,"43719":31482,"43720":31998,"43721":32596,"43722":32652,"43723":32651,"43724":32773,"43725":32954,"43726":32933,"43727":32930,"43728":32945,"43729":32929,"43730":32939,"43731":32937,"43732":32948,"43733":32938,"43734":32943,"43735":33253,"43736":33278,"43737":33293,"43738":33459,"43739":33437,"43740":33433,"43741":33453,"43742":33469,"43743":33439,"43744":33465,"43745":33457,"43746":33452,"43747":33445,"43748":33455,"43749":33464,"43750":33443,"43751":33456,"43752":33470,"43753":33463,"43754":34382,"43755":34417,"43756":21021,"43757":34920,"43758":36555,"43759":36814,"43760":36820,"43761":36817,"43762":37045,"43763":37048,"43764":37041,"43765":37046,"43766":37319,"43767":37329,"43768":38263,"43769":38272,"43770":38428,"43771":38464,"43772":38463,"43773":38459,"43774":38468,"43840":38466,"43841":38585,"43842":38632,"43843":38738,"43844":38750,"43845":20127,"43846":20141,"43847":20142,"43848":20449,"43849":20405,"43850":20399,"43851":20415,"43852":20448,"43853":20433,"43854":20431,"43855":20445,"43856":20419,"43857":20406,"43858":20440,"43859":20447,"43860":20426,"43861":20439,"43862":20398,"43863":20432,"43864":20420,"43865":20418,"43866":20442,"43867":20430,"43868":20446,"43869":20407,"43870":20823,"43871":20882,"43872":20881,"43873":20896,"43874":21070,"43875":21059,"43876":21066,"43877":21069,"43878":21068,"43879":21067,"43880":21063,"43881":21191,"43882":21193,"43883":21187,"43884":21185,"43885":21261,"43886":21335,"43887":21371,"43888":21402,"43889":21467,"43890":21676,"43891":21696,"43892":21672,"43893":21710,"43894":21705,"43895":21688,"43896":21670,"43897":21683,"43898":21703,"43899":21698,"43900":21693,"43901":21674,"43902":21697,"43937":21700,"43938":21704,"43939":21679,"43940":21675,"43941":21681,"43942":21691,"43943":21673,"43944":21671,"43945":21695,"43946":22271,"43947":22402,"43948":22411,"43949":22432,"43950":22435,"43951":22434,"43952":22478,"43953":22446,"43954":22419,"43955":22869,"43956":22865,"43957":22863,"43958":22862,"43959":22864,"43960":23004,"43961":23000,"43962":23039,"43963":23011,"43964":23016,"43965":23043,"43966":23013,"43967":23018,"43968":23002,"43969":23014,"43970":23041,"43971":23035,"43972":23401,"43973":23459,"43974":23462,"43975":23460,"43976":23458,"43977":23461,"43978":23553,"43979":23630,"43980":23631,"43981":23629,"43982":23627,"43983":23769,"43984":23762,"43985":24055,"43986":24093,"43987":24101,"43988":24095,"43989":24189,"43990":24224,"43991":24230,"43992":24314,"43993":24328,"43994":24365,"43995":24421,"43996":24456,"43997":24453,"43998":24458,"43999":24459,"44000":24455,"44001":24460,"44002":24457,"44003":24594,"44004":24605,"44005":24608,"44006":24613,"44007":24590,"44008":24616,"44009":24653,"44010":24688,"44011":24680,"44012":24674,"44013":24646,"44014":24643,"44015":24684,"44016":24683,"44017":24682,"44018":24676,"44019":25153,"44020":25308,"44021":25366,"44022":25353,"44023":25340,"44024":25325,"44025":25345,"44026":25326,"44027":25341,"44028":25351,"44029":25329,"44030":25335,"44096":25327,"44097":25324,"44098":25342,"44099":25332,"44100":25361,"44101":25346,"44102":25919,"44103":25925,"44104":26027,"44105":26045,"44106":26082,"44107":26149,"44108":26157,"44109":26144,"44110":26151,"44111":26159,"44112":26143,"44113":26152,"44114":26161,"44115":26148,"44116":26359,"44117":26623,"44118":26579,"44119":26609,"44120":26580,"44121":26576,"44122":26604,"44123":26550,"44124":26543,"44125":26613,"44126":26601,"44127":26607,"44128":26564,"44129":26577,"44130":26548,"44131":26586,"44132":26597,"44133":26552,"44134":26575,"44135":26590,"44136":26611,"44137":26544,"44138":26585,"44139":26594,"44140":26589,"44141":26578,"44142":27498,"44143":27523,"44144":27526,"44145":27573,"44146":27602,"44147":27607,"44148":27679,"44149":27849,"44150":27915,"44151":27954,"44152":27946,"44153":27969,"44154":27941,"44155":27916,"44156":27953,"44157":27934,"44158":27927,"44193":27963,"44194":27965,"44195":27966,"44196":27958,"44197":27931,"44198":27893,"44199":27961,"44200":27943,"44201":27960,"44202":27945,"44203":27950,"44204":27957,"44205":27918,"44206":27947,"44207":28843,"44208":28858,"44209":28851,"44210":28844,"44211":28847,"44212":28845,"44213":28856,"44214":28846,"44215":28836,"44216":29232,"44217":29298,"44218":29295,"44219":29300,"44220":29417,"44221":29408,"44222":29409,"44223":29623,"44224":29642,"44225":29627,"44226":29618,"44227":29645,"44228":29632,"44229":29619,"44230":29978,"44231":29997,"44232":30031,"44233":30028,"44234":30030,"44235":30027,"44236":30123,"44237":30116,"44238":30117,"44239":30114,"44240":30115,"44241":30328,"44242":30342,"44243":30343,"44244":30344,"44245":30408,"44246":30406,"44247":30403,"44248":30405,"44249":30465,"44250":30457,"44251":30456,"44252":30473,"44253":30475,"44254":30462,"44255":30460,"44256":30471,"44257":30684,"44258":30722,"44259":30740,"44260":30732,"44261":30733,"44262":31046,"44263":31049,"44264":31048,"44265":31047,"44266":31161,"44267":31162,"44268":31185,"44269":31186,"44270":31179,"44271":31359,"44272":31361,"44273":31487,"44274":31485,"44275":31869,"44276":32002,"44277":32005,"44278":32000,"44279":32009,"44280":32007,"44281":32004,"44282":32006,"44283":32568,"44284":32654,"44285":32703,"44286":32772,"44352":32784,"44353":32781,"44354":32785,"44355":32822,"44356":32982,"44357":32997,"44358":32986,"44359":32963,"44360":32964,"44361":32972,"44362":32993,"44363":32987,"44364":32974,"44365":32990,"44366":32996,"44367":32989,"44368":33268,"44369":33314,"44370":33511,"44371":33539,"44372":33541,"44373":33507,"44374":33499,"44375":33510,"44376":33540,"44377":33509,"44378":33538,"44379":33545,"44380":33490,"44381":33495,"44382":33521,"44383":33537,"44384":33500,"44385":33492,"44386":33489,"44387":33502,"44388":33491,"44389":33503,"44390":33519,"44391":33542,"44392":34384,"44393":34425,"44394":34427,"44395":34426,"44396":34893,"44397":34923,"44398":35201,"44399":35284,"44400":35336,"44401":35330,"44402":35331,"44403":35998,"44404":36000,"44405":36212,"44406":36211,"44407":36276,"44408":36557,"44409":36556,"44410":36848,"44411":36838,"44412":36834,"44413":36842,"44414":36837,"44449":36845,"44450":36843,"44451":36836,"44452":36840,"44453":37066,"44454":37070,"44455":37057,"44456":37059,"44457":37195,"44458":37194,"44459":37325,"44460":38274,"44461":38480,"44462":38475,"44463":38476,"44464":38477,"44465":38754,"44466":38761,"44467":38859,"44468":38893,"44469":38899,"44470":38913,"44471":39080,"44472":39131,"44473":39135,"44474":39318,"44475":39321,"44476":20056,"44477":20147,"44478":20492,"44479":20493,"44480":20515,"44481":20463,"44482":20518,"44483":20517,"44484":20472,"44485":20521,"44486":20502,"44487":20486,"44488":20540,"44489":20511,"44490":20506,"44491":20498,"44492":20497,"44493":20474,"44494":20480,"44495":20500,"44496":20520,"44497":20465,"44498":20513,"44499":20491,"44500":20505,"44501":20504,"44502":20467,"44503":20462,"44504":20525,"44505":20522,"44506":20478,"44507":20523,"44508":20489,"44509":20860,"44510":20900,"44511":20901,"44512":20898,"44513":20941,"44514":20940,"44515":20934,"44516":20939,"44517":21078,"44518":21084,"44519":21076,"44520":21083,"44521":21085,"44522":21290,"44523":21375,"44524":21407,"44525":21405,"44526":21471,"44527":21736,"44528":21776,"44529":21761,"44530":21815,"44531":21756,"44532":21733,"44533":21746,"44534":21766,"44535":21754,"44536":21780,"44537":21737,"44538":21741,"44539":21729,"44540":21769,"44541":21742,"44542":21738,"44608":21734,"44609":21799,"44610":21767,"44611":21757,"44612":21775,"44613":22275,"44614":22276,"44615":22466,"44616":22484,"44617":22475,"44618":22467,"44619":22537,"44620":22799,"44621":22871,"44622":22872,"44623":22874,"44624":23057,"44625":23064,"44626":23068,"44627":23071,"44628":23067,"44629":23059,"44630":23020,"44631":23072,"44632":23075,"44633":23081,"44634":23077,"44635":23052,"44636":23049,"44637":23403,"44638":23640,"44639":23472,"44640":23475,"44641":23478,"44642":23476,"44643":23470,"44644":23477,"44645":23481,"44646":23480,"44647":23556,"44648":23633,"44649":23637,"44650":23632,"44651":23789,"44652":23805,"44653":23803,"44654":23786,"44655":23784,"44656":23792,"44657":23798,"44658":23809,"44659":23796,"44660":24046,"44661":24109,"44662":24107,"44663":24235,"44664":24237,"44665":24231,"44666":24369,"44667":24466,"44668":24465,"44669":24464,"44670":24665,"44705":24675,"44706":24677,"44707":24656,"44708":24661,"44709":24685,"44710":24681,"44711":24687,"44712":24708,"44713":24735,"44714":24730,"44715":24717,"44716":24724,"44717":24716,"44718":24709,"44719":24726,"44720":25159,"44721":25331,"44722":25352,"44723":25343,"44724":25422,"44725":25406,"44726":25391,"44727":25429,"44728":25410,"44729":25414,"44730":25423,"44731":25417,"44732":25402,"44733":25424,"44734":25405,"44735":25386,"44736":25387,"44737":25384,"44738":25421,"44739":25420,"44740":25928,"44741":25929,"44742":26009,"44743":26049,"44744":26053,"44745":26178,"44746":26185,"44747":26191,"44748":26179,"44749":26194,"44750":26188,"44751":26181,"44752":26177,"44753":26360,"44754":26388,"44755":26389,"44756":26391,"44757":26657,"44758":26680,"44759":26696,"44760":26694,"44761":26707,"44762":26681,"44763":26690,"44764":26708,"44765":26665,"44766":26803,"44767":26647,"44768":26700,"44769":26705,"44770":26685,"44771":26612,"44772":26704,"44773":26688,"44774":26684,"44775":26691,"44776":26666,"44777":26693,"44778":26643,"44779":26648,"44780":26689,"44781":27530,"44782":27529,"44783":27575,"44784":27683,"44785":27687,"44786":27688,"44787":27686,"44788":27684,"44789":27888,"44790":28010,"44791":28053,"44792":28040,"44793":28039,"44794":28006,"44795":28024,"44796":28023,"44797":27993,"44798":28051,"44864":28012,"44865":28041,"44866":28014,"44867":27994,"44868":28020,"44869":28009,"44870":28044,"44871":28042,"44872":28025,"44873":28037,"44874":28005,"44875":28052,"44876":28874,"44877":28888,"44878":28900,"44879":28889,"44880":28872,"44881":28879,"44882":29241,"44883":29305,"44884":29436,"44885":29433,"44886":29437,"44887":29432,"44888":29431,"44889":29574,"44890":29677,"44891":29705,"44892":29678,"44893":29664,"44894":29674,"44895":29662,"44896":30036,"44897":30045,"44898":30044,"44899":30042,"44900":30041,"44901":30142,"44902":30149,"44903":30151,"44904":30130,"44905":30131,"44906":30141,"44907":30140,"44908":30137,"44909":30146,"44910":30136,"44911":30347,"44912":30384,"44913":30410,"44914":30413,"44915":30414,"44916":30505,"44917":30495,"44918":30496,"44919":30504,"44920":30697,"44921":30768,"44922":30759,"44923":30776,"44924":30749,"44925":30772,"44926":30775,"44961":30757,"44962":30765,"44963":30752,"44964":30751,"44965":30770,"44966":31061,"44967":31056,"44968":31072,"44969":31071,"44970":31062,"44971":31070,"44972":31069,"44973":31063,"44974":31066,"44975":31204,"44976":31203,"44977":31207,"44978":31199,"44979":31206,"44980":31209,"44981":31192,"44982":31364,"44983":31368,"44984":31449,"44985":31494,"44986":31505,"44987":31881,"44988":32033,"44989":32023,"44990":32011,"44991":32010,"44992":32032,"44993":32034,"44994":32020,"44995":32016,"44996":32021,"44997":32026,"44998":32028,"44999":32013,"45000":32025,"45001":32027,"45002":32570,"45003":32607,"45004":32660,"45005":32709,"45006":32705,"45007":32774,"45008":32792,"45009":32789,"45010":32793,"45011":32791,"45012":32829,"45013":32831,"45014":33009,"45015":33026,"45016":33008,"45017":33029,"45018":33005,"45019":33012,"45020":33030,"45021":33016,"45022":33011,"45023":33032,"45024":33021,"45025":33034,"45026":33020,"45027":33007,"45028":33261,"45029":33260,"45030":33280,"45031":33296,"45032":33322,"45033":33323,"45034":33320,"45035":33324,"45036":33467,"45037":33579,"45038":33618,"45039":33620,"45040":33610,"45041":33592,"45042":33616,"45043":33609,"45044":33589,"45045":33588,"45046":33615,"45047":33586,"45048":33593,"45049":33590,"45050":33559,"45051":33600,"45052":33585,"45053":33576,"45054":33603,"45120":34388,"45121":34442,"45122":34474,"45123":34451,"45124":34468,"45125":34473,"45126":34444,"45127":34467,"45128":34460,"45129":34928,"45130":34935,"45131":34945,"45132":34946,"45133":34941,"45134":34937,"45135":35352,"45136":35344,"45137":35342,"45138":35340,"45139":35349,"45140":35338,"45141":35351,"45142":35347,"45143":35350,"45144":35343,"45145":35345,"45146":35912,"45147":35962,"45148":35961,"45149":36001,"45150":36002,"45151":36215,"45152":36524,"45153":36562,"45154":36564,"45155":36559,"45156":36785,"45157":36865,"45158":36870,"45159":36855,"45160":36864,"45161":36858,"45162":36852,"45163":36867,"45164":36861,"45165":36869,"45166":36856,"45167":37013,"45168":37089,"45169":37085,"45170":37090,"45171":37202,"45172":37197,"45173":37196,"45174":37336,"45175":37341,"45176":37335,"45177":37340,"45178":37337,"45179":38275,"45180":38498,"45181":38499,"45182":38497,"45217":38491,"45218":38493,"45219":38500,"45220":38488,"45221":38494,"45222":38587,"45223":39138,"45224":39340,"45225":39592,"45226":39640,"45227":39717,"45228":39730,"45229":39740,"45230":20094,"45231":20602,"45232":20605,"45233":20572,"45234":20551,"45235":20547,"45236":20556,"45237":20570,"45238":20553,"45239":20581,"45240":20598,"45241":20558,"45242":20565,"45243":20597,"45244":20596,"45245":20599,"45246":20559,"45247":20495,"45248":20591,"45249":20589,"45250":20828,"45251":20885,"45252":20976,"45253":21098,"45254":21103,"45255":21202,"45256":21209,"45257":21208,"45258":21205,"45259":21264,"45260":21263,"45261":21273,"45262":21311,"45263":21312,"45264":21310,"45265":21443,"45266":26364,"45267":21830,"45268":21866,"45269":21862,"45270":21828,"45271":21854,"45272":21857,"45273":21827,"45274":21834,"45275":21809,"45276":21846,"45277":21839,"45278":21845,"45279":21807,"45280":21860,"45281":21816,"45282":21806,"45283":21852,"45284":21804,"45285":21859,"45286":21811,"45287":21825,"45288":21847,"45289":22280,"45290":22283,"45291":22281,"45292":22495,"45293":22533,"45294":22538,"45295":22534,"45296":22496,"45297":22500,"45298":22522,"45299":22530,"45300":22581,"45301":22519,"45302":22521,"45303":22816,"45304":22882,"45305":23094,"45306":23105,"45307":23113,"45308":23142,"45309":23146,"45310":23104,"45376":23100,"45377":23138,"45378":23130,"45379":23110,"45380":23114,"45381":23408,"45382":23495,"45383":23493,"45384":23492,"45385":23490,"45386":23487,"45387":23494,"45388":23561,"45389":23560,"45390":23559,"45391":23648,"45392":23644,"45393":23645,"45394":23815,"45395":23814,"45396":23822,"45397":23835,"45398":23830,"45399":23842,"45400":23825,"45401":23849,"45402":23828,"45403":23833,"45404":23844,"45405":23847,"45406":23831,"45407":24034,"45408":24120,"45409":24118,"45410":24115,"45411":24119,"45412":24247,"45413":24248,"45414":24246,"45415":24245,"45416":24254,"45417":24373,"45418":24375,"45419":24407,"45420":24428,"45421":24425,"45422":24427,"45423":24471,"45424":24473,"45425":24478,"45426":24472,"45427":24481,"45428":24480,"45429":24476,"45430":24703,"45431":24739,"45432":24713,"45433":24736,"45434":24744,"45435":24779,"45436":24756,"45437":24806,"45438":24765,"45473":24773,"45474":24763,"45475":24757,"45476":24796,"45477":24764,"45478":24792,"45479":24789,"45480":24774,"45481":24799,"45482":24760,"45483":24794,"45484":24775,"45485":25114,"45486":25115,"45487":25160,"45488":25504,"45489":25511,"45490":25458,"45491":25494,"45492":25506,"45493":25509,"45494":25463,"45495":25447,"45496":25496,"45497":25514,"45498":25457,"45499":25513,"45500":25481,"45501":25475,"45502":25499,"45503":25451,"45504":25512,"45505":25476,"45506":25480,"45507":25497,"45508":25505,"45509":25516,"45510":25490,"45511":25487,"45512":25472,"45513":25467,"45514":25449,"45515":25448,"45516":25466,"45517":25949,"45518":25942,"45519":25937,"45520":25945,"45521":25943,"45522":21855,"45523":25935,"45524":25944,"45525":25941,"45526":25940,"45527":26012,"45528":26011,"45529":26028,"45530":26063,"45531":26059,"45532":26060,"45533":26062,"45534":26205,"45535":26202,"45536":26212,"45537":26216,"45538":26214,"45539":26206,"45540":26361,"45541":21207,"45542":26395,"45543":26753,"45544":26799,"45545":26786,"45546":26771,"45547":26805,"45548":26751,"45549":26742,"45550":26801,"45551":26791,"45552":26775,"45553":26800,"45554":26755,"45555":26820,"45556":26797,"45557":26758,"45558":26757,"45559":26772,"45560":26781,"45561":26792,"45562":26783,"45563":26785,"45564":26754,"45565":27442,"45566":27578,"45632":27627,"45633":27628,"45634":27691,"45635":28046,"45636":28092,"45637":28147,"45638":28121,"45639":28082,"45640":28129,"45641":28108,"45642":28132,"45643":28155,"45644":28154,"45645":28165,"45646":28103,"45647":28107,"45648":28079,"45649":28113,"45650":28078,"45651":28126,"45652":28153,"45653":28088,"45654":28151,"45655":28149,"45656":28101,"45657":28114,"45658":28186,"45659":28085,"45660":28122,"45661":28139,"45662":28120,"45663":28138,"45664":28145,"45665":28142,"45666":28136,"45667":28102,"45668":28100,"45669":28074,"45670":28140,"45671":28095,"45672":28134,"45673":28921,"45674":28937,"45675":28938,"45676":28925,"45677":28911,"45678":29245,"45679":29309,"45680":29313,"45681":29468,"45682":29467,"45683":29462,"45684":29459,"45685":29465,"45686":29575,"45687":29701,"45688":29706,"45689":29699,"45690":29702,"45691":29694,"45692":29709,"45693":29920,"45694":29942,"45729":29943,"45730":29980,"45731":29986,"45732":30053,"45733":30054,"45734":30050,"45735":30064,"45736":30095,"45737":30164,"45738":30165,"45739":30133,"45740":30154,"45741":30157,"45742":30350,"45743":30420,"45744":30418,"45745":30427,"45746":30519,"45747":30526,"45748":30524,"45749":30518,"45750":30520,"45751":30522,"45752":30827,"45753":30787,"45754":30798,"45755":31077,"45756":31080,"45757":31085,"45758":31227,"45759":31378,"45760":31381,"45761":31520,"45762":31528,"45763":31515,"45764":31532,"45765":31526,"45766":31513,"45767":31518,"45768":31534,"45769":31890,"45770":31895,"45771":31893,"45772":32070,"45773":32067,"45774":32113,"45775":32046,"45776":32057,"45777":32060,"45778":32064,"45779":32048,"45780":32051,"45781":32068,"45782":32047,"45783":32066,"45784":32050,"45785":32049,"45786":32573,"45787":32670,"45788":32666,"45789":32716,"45790":32718,"45791":32722,"45792":32796,"45793":32842,"45794":32838,"45795":33071,"45796":33046,"45797":33059,"45798":33067,"45799":33065,"45800":33072,"45801":33060,"45802":33282,"45803":33333,"45804":33335,"45805":33334,"45806":33337,"45807":33678,"45808":33694,"45809":33688,"45810":33656,"45811":33698,"45812":33686,"45813":33725,"45814":33707,"45815":33682,"45816":33674,"45817":33683,"45818":33673,"45819":33696,"45820":33655,"45821":33659,"45822":33660,"45888":33670,"45889":33703,"45890":34389,"45891":24426,"45892":34503,"45893":34496,"45894":34486,"45895":34500,"45896":34485,"45897":34502,"45898":34507,"45899":34481,"45900":34479,"45901":34505,"45902":34899,"45903":34974,"45904":34952,"45905":34987,"45906":34962,"45907":34966,"45908":34957,"45909":34955,"45910":35219,"45911":35215,"45912":35370,"45913":35357,"45914":35363,"45915":35365,"45916":35377,"45917":35373,"45918":35359,"45919":35355,"45920":35362,"45921":35913,"45922":35930,"45923":36009,"45924":36012,"45925":36011,"45926":36008,"45927":36010,"45928":36007,"45929":36199,"45930":36198,"45931":36286,"45932":36282,"45933":36571,"45934":36575,"45935":36889,"45936":36877,"45937":36890,"45938":36887,"45939":36899,"45940":36895,"45941":36893,"45942":36880,"45943":36885,"45944":36894,"45945":36896,"45946":36879,"45947":36898,"45948":36886,"45949":36891,"45950":36884,"45985":37096,"45986":37101,"45987":37117,"45988":37207,"45989":37326,"45990":37365,"45991":37350,"45992":37347,"45993":37351,"45994":37357,"45995":37353,"45996":38281,"45997":38506,"45998":38517,"45999":38515,"46000":38520,"46001":38512,"46002":38516,"46003":38518,"46004":38519,"46005":38508,"46006":38592,"46007":38634,"46008":38633,"46009":31456,"46010":31455,"46011":38914,"46012":38915,"46013":39770,"46014":40165,"46015":40565,"46016":40575,"46017":40613,"46018":40635,"46019":20642,"46020":20621,"46021":20613,"46022":20633,"46023":20625,"46024":20608,"46025":20630,"46026":20632,"46027":20634,"46028":26368,"46029":20977,"46030":21106,"46031":21108,"46032":21109,"46033":21097,"46034":21214,"46035":21213,"46036":21211,"46037":21338,"46038":21413,"46039":21883,"46040":21888,"46041":21927,"46042":21884,"46043":21898,"46044":21917,"46045":21912,"46046":21890,"46047":21916,"46048":21930,"46049":21908,"46050":21895,"46051":21899,"46052":21891,"46053":21939,"46054":21934,"46055":21919,"46056":21822,"46057":21938,"46058":21914,"46059":21947,"46060":21932,"46061":21937,"46062":21886,"46063":21897,"46064":21931,"46065":21913,"46066":22285,"46067":22575,"46068":22570,"46069":22580,"46070":22564,"46071":22576,"46072":22577,"46073":22561,"46074":22557,"46075":22560,"46076":22777,"46077":22778,"46078":22880,"46144":23159,"46145":23194,"46146":23167,"46147":23186,"46148":23195,"46149":23207,"46150":23411,"46151":23409,"46152":23506,"46153":23500,"46154":23507,"46155":23504,"46156":23562,"46157":23563,"46158":23601,"46159":23884,"46160":23888,"46161":23860,"46162":23879,"46163":24061,"46164":24133,"46165":24125,"46166":24128,"46167":24131,"46168":24190,"46169":24266,"46170":24257,"46171":24258,"46172":24260,"46173":24380,"46174":24429,"46175":24489,"46176":24490,"46177":24488,"46178":24785,"46179":24801,"46180":24754,"46181":24758,"46182":24800,"46183":24860,"46184":24867,"46185":24826,"46186":24853,"46187":24816,"46188":24827,"46189":24820,"46190":24936,"46191":24817,"46192":24846,"46193":24822,"46194":24841,"46195":24832,"46196":24850,"46197":25119,"46198":25161,"46199":25507,"46200":25484,"46201":25551,"46202":25536,"46203":25577,"46204":25545,"46205":25542,"46206":25549,"46241":25554,"46242":25571,"46243":25552,"46244":25569,"46245":25558,"46246":25581,"46247":25582,"46248":25462,"46249":25588,"46250":25578,"46251":25563,"46252":25682,"46253":25562,"46254":25593,"46255":25950,"46256":25958,"46257":25954,"46258":25955,"46259":26001,"46260":26000,"46261":26031,"46262":26222,"46263":26224,"46264":26228,"46265":26230,"46266":26223,"46267":26257,"46268":26234,"46269":26238,"46270":26231,"46271":26366,"46272":26367,"46273":26399,"46274":26397,"46275":26874,"46276":26837,"46277":26848,"46278":26840,"46279":26839,"46280":26885,"46281":26847,"46282":26869,"46283":26862,"46284":26855,"46285":26873,"46286":26834,"46287":26866,"46288":26851,"46289":26827,"46290":26829,"46291":26893,"46292":26898,"46293":26894,"46294":26825,"46295":26842,"46296":26990,"46297":26875,"46298":27454,"46299":27450,"46300":27453,"46301":27544,"46302":27542,"46303":27580,"46304":27631,"46305":27694,"46306":27695,"46307":27692,"46308":28207,"46309":28216,"46310":28244,"46311":28193,"46312":28210,"46313":28263,"46314":28234,"46315":28192,"46316":28197,"46317":28195,"46318":28187,"46319":28251,"46320":28248,"46321":28196,"46322":28246,"46323":28270,"46324":28205,"46325":28198,"46326":28271,"46327":28212,"46328":28237,"46329":28218,"46330":28204,"46331":28227,"46332":28189,"46333":28222,"46334":28363,"46400":28297,"46401":28185,"46402":28238,"46403":28259,"46404":28228,"46405":28274,"46406":28265,"46407":28255,"46408":28953,"46409":28954,"46410":28966,"46411":28976,"46412":28961,"46413":28982,"46414":29038,"46415":28956,"46416":29260,"46417":29316,"46418":29312,"46419":29494,"46420":29477,"46421":29492,"46422":29481,"46423":29754,"46424":29738,"46425":29747,"46426":29730,"46427":29733,"46428":29749,"46429":29750,"46430":29748,"46431":29743,"46432":29723,"46433":29734,"46434":29736,"46435":29989,"46436":29990,"46437":30059,"46438":30058,"46439":30178,"46440":30171,"46441":30179,"46442":30169,"46443":30168,"46444":30174,"46445":30176,"46446":30331,"46447":30332,"46448":30358,"46449":30355,"46450":30388,"46451":30428,"46452":30543,"46453":30701,"46454":30813,"46455":30828,"46456":30831,"46457":31245,"46458":31240,"46459":31243,"46460":31237,"46461":31232,"46462":31384,"46497":31383,"46498":31382,"46499":31461,"46500":31459,"46501":31561,"46502":31574,"46503":31558,"46504":31568,"46505":31570,"46506":31572,"46507":31565,"46508":31563,"46509":31567,"46510":31569,"46511":31903,"46512":31909,"46513":32094,"46514":32080,"46515":32104,"46516":32085,"46517":32043,"46518":32110,"46519":32114,"46520":32097,"46521":32102,"46522":32098,"46523":32112,"46524":32115,"46525":21892,"46526":32724,"46527":32725,"46528":32779,"46529":32850,"46530":32901,"46531":33109,"46532":33108,"46533":33099,"46534":33105,"46535":33102,"46536":33081,"46537":33094,"46538":33086,"46539":33100,"46540":33107,"46541":33140,"46542":33298,"46543":33308,"46544":33769,"46545":33795,"46546":33784,"46547":33805,"46548":33760,"46549":33733,"46550":33803,"46551":33729,"46552":33775,"46553":33777,"46554":33780,"46555":33879,"46556":33802,"46557":33776,"46558":33804,"46559":33740,"46560":33789,"46561":33778,"46562":33738,"46563":33848,"46564":33806,"46565":33796,"46566":33756,"46567":33799,"46568":33748,"46569":33759,"46570":34395,"46571":34527,"46572":34521,"46573":34541,"46574":34516,"46575":34523,"46576":34532,"46577":34512,"46578":34526,"46579":34903,"46580":35009,"46581":35010,"46582":34993,"46583":35203,"46584":35222,"46585":35387,"46586":35424,"46587":35413,"46588":35422,"46589":35388,"46590":35393,"46656":35412,"46657":35419,"46658":35408,"46659":35398,"46660":35380,"46661":35386,"46662":35382,"46663":35414,"46664":35937,"46665":35970,"46666":36015,"46667":36028,"46668":36019,"46669":36029,"46670":36033,"46671":36027,"46672":36032,"46673":36020,"46674":36023,"46675":36022,"46676":36031,"46677":36024,"46678":36234,"46679":36229,"46680":36225,"46681":36302,"46682":36317,"46683":36299,"46684":36314,"46685":36305,"46686":36300,"46687":36315,"46688":36294,"46689":36603,"46690":36600,"46691":36604,"46692":36764,"46693":36910,"46694":36917,"46695":36913,"46696":36920,"46697":36914,"46698":36918,"46699":37122,"46700":37109,"46701":37129,"46702":37118,"46703":37219,"46704":37221,"46705":37327,"46706":37396,"46707":37397,"46708":37411,"46709":37385,"46710":37406,"46711":37389,"46712":37392,"46713":37383,"46714":37393,"46715":38292,"46716":38287,"46717":38283,"46718":38289,"46753":38291,"46754":38290,"46755":38286,"46756":38538,"46757":38542,"46758":38539,"46759":38525,"46760":38533,"46761":38534,"46762":38541,"46763":38514,"46764":38532,"46765":38593,"46766":38597,"46767":38596,"46768":38598,"46769":38599,"46770":38639,"46771":38642,"46772":38860,"46773":38917,"46774":38918,"46775":38920,"46776":39143,"46777":39146,"46778":39151,"46779":39145,"46780":39154,"46781":39149,"46782":39342,"46783":39341,"46784":40643,"46785":40653,"46786":40657,"46787":20098,"46788":20653,"46789":20661,"46790":20658,"46791":20659,"46792":20677,"46793":20670,"46794":20652,"46795":20663,"46796":20667,"46797":20655,"46798":20679,"46799":21119,"46800":21111,"46801":21117,"46802":21215,"46803":21222,"46804":21220,"46805":21218,"46806":21219,"46807":21295,"46808":21983,"46809":21992,"46810":21971,"46811":21990,"46812":21966,"46813":21980,"46814":21959,"46815":21969,"46816":21987,"46817":21988,"46818":21999,"46819":21978,"46820":21985,"46821":21957,"46822":21958,"46823":21989,"46824":21961,"46825":22290,"46826":22291,"46827":22622,"46828":22609,"46829":22616,"46830":22615,"46831":22618,"46832":22612,"46833":22635,"46834":22604,"46835":22637,"46836":22602,"46837":22626,"46838":22610,"46839":22603,"46840":22887,"46841":23233,"46842":23241,"46843":23244,"46844":23230,"46845":23229,"46846":23228,"46912":23219,"46913":23234,"46914":23218,"46915":23913,"46916":23919,"46917":24140,"46918":24185,"46919":24265,"46920":24264,"46921":24338,"46922":24409,"46923":24492,"46924":24494,"46925":24858,"46926":24847,"46927":24904,"46928":24863,"46929":24819,"46930":24859,"46931":24825,"46932":24833,"46933":24840,"46934":24910,"46935":24908,"46936":24900,"46937":24909,"46938":24894,"46939":24884,"46940":24871,"46941":24845,"46942":24838,"46943":24887,"46944":25121,"46945":25122,"46946":25619,"46947":25662,"46948":25630,"46949":25642,"46950":25645,"46951":25661,"46952":25644,"46953":25615,"46954":25628,"46955":25620,"46956":25613,"46957":25654,"46958":25622,"46959":25623,"46960":25606,"46961":25964,"46962":26015,"46963":26032,"46964":26263,"46965":26249,"46966":26247,"46967":26248,"46968":26262,"46969":26244,"46970":26264,"46971":26253,"46972":26371,"46973":27028,"46974":26989,"47009":26970,"47010":26999,"47011":26976,"47012":26964,"47013":26997,"47014":26928,"47015":27010,"47016":26954,"47017":26984,"47018":26987,"47019":26974,"47020":26963,"47021":27001,"47022":27014,"47023":26973,"47024":26979,"47025":26971,"47026":27463,"47027":27506,"47028":27584,"47029":27583,"47030":27603,"47031":27645,"47032":28322,"47033":28335,"47034":28371,"47035":28342,"47036":28354,"47037":28304,"47038":28317,"47039":28359,"47040":28357,"47041":28325,"47042":28312,"47043":28348,"47044":28346,"47045":28331,"47046":28369,"47047":28310,"47048":28316,"47049":28356,"47050":28372,"47051":28330,"47052":28327,"47053":28340,"47054":29006,"47055":29017,"47056":29033,"47057":29028,"47058":29001,"47059":29031,"47060":29020,"47061":29036,"47062":29030,"47063":29004,"47064":29029,"47065":29022,"47066":28998,"47067":29032,"47068":29014,"47069":29242,"47070":29266,"47071":29495,"47072":29509,"47073":29503,"47074":29502,"47075":29807,"47076":29786,"47077":29781,"47078":29791,"47079":29790,"47080":29761,"47081":29759,"47082":29785,"47083":29787,"47084":29788,"47085":30070,"47086":30072,"47087":30208,"47088":30192,"47089":30209,"47090":30194,"47091":30193,"47092":30202,"47093":30207,"47094":30196,"47095":30195,"47096":30430,"47097":30431,"47098":30555,"47099":30571,"47100":30566,"47101":30558,"47102":30563,"47168":30585,"47169":30570,"47170":30572,"47171":30556,"47172":30565,"47173":30568,"47174":30562,"47175":30702,"47176":30862,"47177":30896,"47178":30871,"47179":30872,"47180":30860,"47181":30857,"47182":30844,"47183":30865,"47184":30867,"47185":30847,"47186":31098,"47187":31103,"47188":31105,"47189":33836,"47190":31165,"47191":31260,"47192":31258,"47193":31264,"47194":31252,"47195":31263,"47196":31262,"47197":31391,"47198":31392,"47199":31607,"47200":31680,"47201":31584,"47202":31598,"47203":31591,"47204":31921,"47205":31923,"47206":31925,"47207":32147,"47208":32121,"47209":32145,"47210":32129,"47211":32143,"47212":32091,"47213":32622,"47214":32617,"47215":32618,"47216":32626,"47217":32681,"47218":32680,"47219":32676,"47220":32854,"47221":32856,"47222":32902,"47223":32900,"47224":33137,"47225":33136,"47226":33144,"47227":33125,"47228":33134,"47229":33139,"47230":33131,"47265":33145,"47266":33146,"47267":33126,"47268":33285,"47269":33351,"47270":33922,"47271":33911,"47272":33853,"47273":33841,"47274":33909,"47275":33894,"47276":33899,"47277":33865,"47278":33900,"47279":33883,"47280":33852,"47281":33845,"47282":33889,"47283":33891,"47284":33897,"47285":33901,"47286":33862,"47287":34398,"47288":34396,"47289":34399,"47290":34553,"47291":34579,"47292":34568,"47293":34567,"47294":34560,"47295":34558,"47296":34555,"47297":34562,"47298":34563,"47299":34566,"47300":34570,"47301":34905,"47302":35039,"47303":35028,"47304":35033,"47305":35036,"47306":35032,"47307":35037,"47308":35041,"47309":35018,"47310":35029,"47311":35026,"47312":35228,"47313":35299,"47314":35435,"47315":35442,"47316":35443,"47317":35430,"47318":35433,"47319":35440,"47320":35463,"47321":35452,"47322":35427,"47323":35488,"47324":35441,"47325":35461,"47326":35437,"47327":35426,"47328":35438,"47329":35436,"47330":35449,"47331":35451,"47332":35390,"47333":35432,"47334":35938,"47335":35978,"47336":35977,"47337":36042,"47338":36039,"47339":36040,"47340":36036,"47341":36018,"47342":36035,"47343":36034,"47344":36037,"47345":36321,"47346":36319,"47347":36328,"47348":36335,"47349":36339,"47350":36346,"47351":36330,"47352":36324,"47353":36326,"47354":36530,"47355":36611,"47356":36617,"47357":36606,"47358":36618,"47424":36767,"47425":36786,"47426":36939,"47427":36938,"47428":36947,"47429":36930,"47430":36948,"47431":36924,"47432":36949,"47433":36944,"47434":36935,"47435":36943,"47436":36942,"47437":36941,"47438":36945,"47439":36926,"47440":36929,"47441":37138,"47442":37143,"47443":37228,"47444":37226,"47445":37225,"47446":37321,"47447":37431,"47448":37463,"47449":37432,"47450":37437,"47451":37440,"47452":37438,"47453":37467,"47454":37451,"47455":37476,"47456":37457,"47457":37428,"47458":37449,"47459":37453,"47460":37445,"47461":37433,"47462":37439,"47463":37466,"47464":38296,"47465":38552,"47466":38548,"47467":38549,"47468":38605,"47469":38603,"47470":38601,"47471":38602,"47472":38647,"47473":38651,"47474":38649,"47475":38646,"47476":38742,"47477":38772,"47478":38774,"47479":38928,"47480":38929,"47481":38931,"47482":38922,"47483":38930,"47484":38924,"47485":39164,"47486":39156,"47521":39165,"47522":39166,"47523":39347,"47524":39345,"47525":39348,"47526":39649,"47527":40169,"47528":40578,"47529":40718,"47530":40723,"47531":40736,"47532":20711,"47533":20718,"47534":20709,"47535":20694,"47536":20717,"47537":20698,"47538":20693,"47539":20687,"47540":20689,"47541":20721,"47542":20686,"47543":20713,"47544":20834,"47545":20979,"47546":21123,"47547":21122,"47548":21297,"47549":21421,"47550":22014,"47551":22016,"47552":22043,"47553":22039,"47554":22013,"47555":22036,"47556":22022,"47557":22025,"47558":22029,"47559":22030,"47560":22007,"47561":22038,"47562":22047,"47563":22024,"47564":22032,"47565":22006,"47566":22296,"47567":22294,"47568":22645,"47569":22654,"47570":22659,"47571":22675,"47572":22666,"47573":22649,"47574":22661,"47575":22653,"47576":22781,"47577":22821,"47578":22818,"47579":22820,"47580":22890,"47581":22889,"47582":23265,"47583":23270,"47584":23273,"47585":23255,"47586":23254,"47587":23256,"47588":23267,"47589":23413,"47590":23518,"47591":23527,"47592":23521,"47593":23525,"47594":23526,"47595":23528,"47596":23522,"47597":23524,"47598":23519,"47599":23565,"47600":23650,"47601":23940,"47602":23943,"47603":24155,"47604":24163,"47605":24149,"47606":24151,"47607":24148,"47608":24275,"47609":24278,"47610":24330,"47611":24390,"47612":24432,"47613":24505,"47614":24903,"47680":24895,"47681":24907,"47682":24951,"47683":24930,"47684":24931,"47685":24927,"47686":24922,"47687":24920,"47688":24949,"47689":25130,"47690":25735,"47691":25688,"47692":25684,"47693":25764,"47694":25720,"47695":25695,"47696":25722,"47697":25681,"47698":25703,"47699":25652,"47700":25709,"47701":25723,"47702":25970,"47703":26017,"47704":26071,"47705":26070,"47706":26274,"47707":26280,"47708":26269,"47709":27036,"47710":27048,"47711":27029,"47712":27073,"47713":27054,"47714":27091,"47715":27083,"47716":27035,"47717":27063,"47718":27067,"47719":27051,"47720":27060,"47721":27088,"47722":27085,"47723":27053,"47724":27084,"47725":27046,"47726":27075,"47727":27043,"47728":27465,"47729":27468,"47730":27699,"47731":28467,"47732":28436,"47733":28414,"47734":28435,"47735":28404,"47736":28457,"47737":28478,"47738":28448,"47739":28460,"47740":28431,"47741":28418,"47742":28450,"47777":28415,"47778":28399,"47779":28422,"47780":28465,"47781":28472,"47782":28466,"47783":28451,"47784":28437,"47785":28459,"47786":28463,"47787":28552,"47788":28458,"47789":28396,"47790":28417,"47791":28402,"47792":28364,"47793":28407,"47794":29076,"47795":29081,"47796":29053,"47797":29066,"47798":29060,"47799":29074,"47800":29246,"47801":29330,"47802":29334,"47803":29508,"47804":29520,"47805":29796,"47806":29795,"47807":29802,"47808":29808,"47809":29805,"47810":29956,"47811":30097,"47812":30247,"47813":30221,"47814":30219,"47815":30217,"47816":30227,"47817":30433,"47818":30435,"47819":30596,"47820":30589,"47821":30591,"47822":30561,"47823":30913,"47824":30879,"47825":30887,"47826":30899,"47827":30889,"47828":30883,"47829":31118,"47830":31119,"47831":31117,"47832":31278,"47833":31281,"47834":31402,"47835":31401,"47836":31469,"47837":31471,"47838":31649,"47839":31637,"47840":31627,"47841":31605,"47842":31639,"47843":31645,"47844":31636,"47845":31631,"47846":31672,"47847":31623,"47848":31620,"47849":31929,"47850":31933,"47851":31934,"47852":32187,"47853":32176,"47854":32156,"47855":32189,"47856":32190,"47857":32160,"47858":32202,"47859":32180,"47860":32178,"47861":32177,"47862":32186,"47863":32162,"47864":32191,"47865":32181,"47866":32184,"47867":32173,"47868":32210,"47869":32199,"47870":32172,"47936":32624,"47937":32736,"47938":32737,"47939":32735,"47940":32862,"47941":32858,"47942":32903,"47943":33104,"47944":33152,"47945":33167,"47946":33160,"47947":33162,"47948":33151,"47949":33154,"47950":33255,"47951":33274,"47952":33287,"47953":33300,"47954":33310,"47955":33355,"47956":33993,"47957":33983,"47958":33990,"47959":33988,"47960":33945,"47961":33950,"47962":33970,"47963":33948,"47964":33995,"47965":33976,"47966":33984,"47967":34003,"47968":33936,"47969":33980,"47970":34001,"47971":33994,"47972":34623,"47973":34588,"47974":34619,"47975":34594,"47976":34597,"47977":34612,"47978":34584,"47979":34645,"47980":34615,"47981":34601,"47982":35059,"47983":35074,"47984":35060,"47985":35065,"47986":35064,"47987":35069,"47988":35048,"47989":35098,"47990":35055,"47991":35494,"47992":35468,"47993":35486,"47994":35491,"47995":35469,"47996":35489,"47997":35475,"47998":35492,"48033":35498,"48034":35493,"48035":35496,"48036":35480,"48037":35473,"48038":35482,"48039":35495,"48040":35946,"48041":35981,"48042":35980,"48043":36051,"48044":36049,"48045":36050,"48046":36203,"48047":36249,"48048":36245,"48049":36348,"48050":36628,"48051":36626,"48052":36629,"48053":36627,"48054":36771,"48055":36960,"48056":36952,"48057":36956,"48058":36963,"48059":36953,"48060":36958,"48061":36962,"48062":36957,"48063":36955,"48064":37145,"48065":37144,"48066":37150,"48067":37237,"48068":37240,"48069":37239,"48070":37236,"48071":37496,"48072":37504,"48073":37509,"48074":37528,"48075":37526,"48076":37499,"48077":37523,"48078":37532,"48079":37544,"48080":37500,"48081":37521,"48082":38305,"48083":38312,"48084":38313,"48085":38307,"48086":38309,"48087":38308,"48088":38553,"48089":38556,"48090":38555,"48091":38604,"48092":38610,"48093":38656,"48094":38780,"48095":38789,"48096":38902,"48097":38935,"48098":38936,"48099":39087,"48100":39089,"48101":39171,"48102":39173,"48103":39180,"48104":39177,"48105":39361,"48106":39599,"48107":39600,"48108":39654,"48109":39745,"48110":39746,"48111":40180,"48112":40182,"48113":40179,"48114":40636,"48115":40763,"48116":40778,"48117":20740,"48118":20736,"48119":20731,"48120":20725,"48121":20729,"48122":20738,"48123":20744,"48124":20745,"48125":20741,"48126":20956,"48192":21127,"48193":21128,"48194":21129,"48195":21133,"48196":21130,"48197":21232,"48198":21426,"48199":22062,"48200":22075,"48201":22073,"48202":22066,"48203":22079,"48204":22068,"48205":22057,"48206":22099,"48207":22094,"48208":22103,"48209":22132,"48210":22070,"48211":22063,"48212":22064,"48213":22656,"48214":22687,"48215":22686,"48216":22707,"48217":22684,"48218":22702,"48219":22697,"48220":22694,"48221":22893,"48222":23305,"48223":23291,"48224":23307,"48225":23285,"48226":23308,"48227":23304,"48228":23534,"48229":23532,"48230":23529,"48231":23531,"48232":23652,"48233":23653,"48234":23965,"48235":23956,"48236":24162,"48237":24159,"48238":24161,"48239":24290,"48240":24282,"48241":24287,"48242":24285,"48243":24291,"48244":24288,"48245":24392,"48246":24433,"48247":24503,"48248":24501,"48249":24950,"48250":24935,"48251":24942,"48252":24925,"48253":24917,"48254":24962,"48289":24956,"48290":24944,"48291":24939,"48292":24958,"48293":24999,"48294":24976,"48295":25003,"48296":24974,"48297":25004,"48298":24986,"48299":24996,"48300":24980,"48301":25006,"48302":25134,"48303":25705,"48304":25711,"48305":25721,"48306":25758,"48307":25778,"48308":25736,"48309":25744,"48310":25776,"48311":25765,"48312":25747,"48313":25749,"48314":25769,"48315":25746,"48316":25774,"48317":25773,"48318":25771,"48319":25754,"48320":25772,"48321":25753,"48322":25762,"48323":25779,"48324":25973,"48325":25975,"48326":25976,"48327":26286,"48328":26283,"48329":26292,"48330":26289,"48331":27171,"48332":27167,"48333":27112,"48334":27137,"48335":27166,"48336":27161,"48337":27133,"48338":27169,"48339":27155,"48340":27146,"48341":27123,"48342":27138,"48343":27141,"48344":27117,"48345":27153,"48346":27472,"48347":27470,"48348":27556,"48349":27589,"48350":27590,"48351":28479,"48352":28540,"48353":28548,"48354":28497,"48355":28518,"48356":28500,"48357":28550,"48358":28525,"48359":28507,"48360":28536,"48361":28526,"48362":28558,"48363":28538,"48364":28528,"48365":28516,"48366":28567,"48367":28504,"48368":28373,"48369":28527,"48370":28512,"48371":28511,"48372":29087,"48373":29100,"48374":29105,"48375":29096,"48376":29270,"48377":29339,"48378":29518,"48379":29527,"48380":29801,"48381":29835,"48382":29827,"48448":29822,"48449":29824,"48450":30079,"48451":30240,"48452":30249,"48453":30239,"48454":30244,"48455":30246,"48456":30241,"48457":30242,"48458":30362,"48459":30394,"48460":30436,"48461":30606,"48462":30599,"48463":30604,"48464":30609,"48465":30603,"48466":30923,"48467":30917,"48468":30906,"48469":30922,"48470":30910,"48471":30933,"48472":30908,"48473":30928,"48474":31295,"48475":31292,"48476":31296,"48477":31293,"48478":31287,"48479":31291,"48480":31407,"48481":31406,"48482":31661,"48483":31665,"48484":31684,"48485":31668,"48486":31686,"48487":31687,"48488":31681,"48489":31648,"48490":31692,"48491":31946,"48492":32224,"48493":32244,"48494":32239,"48495":32251,"48496":32216,"48497":32236,"48498":32221,"48499":32232,"48500":32227,"48501":32218,"48502":32222,"48503":32233,"48504":32158,"48505":32217,"48506":32242,"48507":32249,"48508":32629,"48509":32631,"48510":32687,"48545":32745,"48546":32806,"48547":33179,"48548":33180,"48549":33181,"48550":33184,"48551":33178,"48552":33176,"48553":34071,"48554":34109,"48555":34074,"48556":34030,"48557":34092,"48558":34093,"48559":34067,"48560":34065,"48561":34083,"48562":34081,"48563":34068,"48564":34028,"48565":34085,"48566":34047,"48567":34054,"48568":34690,"48569":34676,"48570":34678,"48571":34656,"48572":34662,"48573":34680,"48574":34664,"48575":34649,"48576":34647,"48577":34636,"48578":34643,"48579":34907,"48580":34909,"48581":35088,"48582":35079,"48583":35090,"48584":35091,"48585":35093,"48586":35082,"48587":35516,"48588":35538,"48589":35527,"48590":35524,"48591":35477,"48592":35531,"48593":35576,"48594":35506,"48595":35529,"48596":35522,"48597":35519,"48598":35504,"48599":35542,"48600":35533,"48601":35510,"48602":35513,"48603":35547,"48604":35916,"48605":35918,"48606":35948,"48607":36064,"48608":36062,"48609":36070,"48610":36068,"48611":36076,"48612":36077,"48613":36066,"48614":36067,"48615":36060,"48616":36074,"48617":36065,"48618":36205,"48619":36255,"48620":36259,"48621":36395,"48622":36368,"48623":36381,"48624":36386,"48625":36367,"48626":36393,"48627":36383,"48628":36385,"48629":36382,"48630":36538,"48631":36637,"48632":36635,"48633":36639,"48634":36649,"48635":36646,"48636":36650,"48637":36636,"48638":36638,"48704":36645,"48705":36969,"48706":36974,"48707":36968,"48708":36973,"48709":36983,"48710":37168,"48711":37165,"48712":37159,"48713":37169,"48714":37255,"48715":37257,"48716":37259,"48717":37251,"48718":37573,"48719":37563,"48720":37559,"48721":37610,"48722":37548,"48723":37604,"48724":37569,"48725":37555,"48726":37564,"48727":37586,"48728":37575,"48729":37616,"48730":37554,"48731":38317,"48732":38321,"48733":38660,"48734":38662,"48735":38663,"48736":38665,"48737":38752,"48738":38797,"48739":38795,"48740":38799,"48741":38945,"48742":38955,"48743":38940,"48744":39091,"48745":39178,"48746":39187,"48747":39186,"48748":39192,"48749":39389,"48750":39376,"48751":39391,"48752":39387,"48753":39377,"48754":39381,"48755":39378,"48756":39385,"48757":39607,"48758":39662,"48759":39663,"48760":39719,"48761":39749,"48762":39748,"48763":39799,"48764":39791,"48765":40198,"48766":40201,"48801":40195,"48802":40617,"48803":40638,"48804":40654,"48805":22696,"48806":40786,"48807":20754,"48808":20760,"48809":20756,"48810":20752,"48811":20757,"48812":20864,"48813":20906,"48814":20957,"48815":21137,"48816":21139,"48817":21235,"48818":22105,"48819":22123,"48820":22137,"48821":22121,"48822":22116,"48823":22136,"48824":22122,"48825":22120,"48826":22117,"48827":22129,"48828":22127,"48829":22124,"48830":22114,"48831":22134,"48832":22721,"48833":22718,"48834":22727,"48835":22725,"48836":22894,"48837":23325,"48838":23348,"48839":23416,"48840":23536,"48841":23566,"48842":24394,"48843":25010,"48844":24977,"48845":25001,"48846":24970,"48847":25037,"48848":25014,"48849":25022,"48850":25034,"48851":25032,"48852":25136,"48853":25797,"48854":25793,"48855":25803,"48856":25787,"48857":25788,"48858":25818,"48859":25796,"48860":25799,"48861":25794,"48862":25805,"48863":25791,"48864":25810,"48865":25812,"48866":25790,"48867":25972,"48868":26310,"48869":26313,"48870":26297,"48871":26308,"48872":26311,"48873":26296,"48874":27197,"48875":27192,"48876":27194,"48877":27225,"48878":27243,"48879":27224,"48880":27193,"48881":27204,"48882":27234,"48883":27233,"48884":27211,"48885":27207,"48886":27189,"48887":27231,"48888":27208,"48889":27481,"48890":27511,"48891":27653,"48892":28610,"48893":28593,"48894":28577,"48960":28611,"48961":28580,"48962":28609,"48963":28583,"48964":28595,"48965":28608,"48966":28601,"48967":28598,"48968":28582,"48969":28576,"48970":28596,"48971":29118,"48972":29129,"48973":29136,"48974":29138,"48975":29128,"48976":29141,"48977":29113,"48978":29134,"48979":29145,"48980":29148,"48981":29123,"48982":29124,"48983":29544,"48984":29852,"48985":29859,"48986":29848,"48987":29855,"48988":29854,"48989":29922,"48990":29964,"48991":29965,"48992":30260,"48993":30264,"48994":30266,"48995":30439,"48996":30437,"48997":30624,"48998":30622,"48999":30623,"49000":30629,"49001":30952,"49002":30938,"49003":30956,"49004":30951,"49005":31142,"49006":31309,"49007":31310,"49008":31302,"49009":31308,"49010":31307,"49011":31418,"49012":31705,"49013":31761,"49014":31689,"49015":31716,"49016":31707,"49017":31713,"49018":31721,"49019":31718,"49020":31957,"49021":31958,"49022":32266,"49057":32273,"49058":32264,"49059":32283,"49060":32291,"49061":32286,"49062":32285,"49063":32265,"49064":32272,"49065":32633,"49066":32690,"49067":32752,"49068":32753,"49069":32750,"49070":32808,"49071":33203,"49072":33193,"49073":33192,"49074":33275,"49075":33288,"49076":33368,"49077":33369,"49078":34122,"49079":34137,"49080":34120,"49081":34152,"49082":34153,"49083":34115,"49084":34121,"49085":34157,"49086":34154,"49087":34142,"49088":34691,"49089":34719,"49090":34718,"49091":34722,"49092":34701,"49093":34913,"49094":35114,"49095":35122,"49096":35109,"49097":35115,"49098":35105,"49099":35242,"49100":35238,"49101":35558,"49102":35578,"49103":35563,"49104":35569,"49105":35584,"49106":35548,"49107":35559,"49108":35566,"49109":35582,"49110":35585,"49111":35586,"49112":35575,"49113":35565,"49114":35571,"49115":35574,"49116":35580,"49117":35947,"49118":35949,"49119":35987,"49120":36084,"49121":36420,"49122":36401,"49123":36404,"49124":36418,"49125":36409,"49126":36405,"49127":36667,"49128":36655,"49129":36664,"49130":36659,"49131":36776,"49132":36774,"49133":36981,"49134":36980,"49135":36984,"49136":36978,"49137":36988,"49138":36986,"49139":37172,"49140":37266,"49141":37664,"49142":37686,"49143":37624,"49144":37683,"49145":37679,"49146":37666,"49147":37628,"49148":37675,"49149":37636,"49150":37658,"49216":37648,"49217":37670,"49218":37665,"49219":37653,"49220":37678,"49221":37657,"49222":38331,"49223":38567,"49224":38568,"49225":38570,"49226":38613,"49227":38670,"49228":38673,"49229":38678,"49230":38669,"49231":38675,"49232":38671,"49233":38747,"49234":38748,"49235":38758,"49236":38808,"49237":38960,"49238":38968,"49239":38971,"49240":38967,"49241":38957,"49242":38969,"49243":38948,"49244":39184,"49245":39208,"49246":39198,"49247":39195,"49248":39201,"49249":39194,"49250":39405,"49251":39394,"49252":39409,"49253":39608,"49254":39612,"49255":39675,"49256":39661,"49257":39720,"49258":39825,"49259":40213,"49260":40227,"49261":40230,"49262":40232,"49263":40210,"49264":40219,"49265":40664,"49266":40660,"49267":40845,"49268":40860,"49269":20778,"49270":20767,"49271":20769,"49272":20786,"49273":21237,"49274":22158,"49275":22144,"49276":22160,"49277":22149,"49278":22151,"49313":22159,"49314":22741,"49315":22739,"49316":22737,"49317":22734,"49318":23344,"49319":23338,"49320":23332,"49321":23418,"49322":23607,"49323":23656,"49324":23996,"49325":23994,"49326":23997,"49327":23992,"49328":24171,"49329":24396,"49330":24509,"49331":25033,"49332":25026,"49333":25031,"49334":25062,"49335":25035,"49336":25138,"49337":25140,"49338":25806,"49339":25802,"49340":25816,"49341":25824,"49342":25840,"49343":25830,"49344":25836,"49345":25841,"49346":25826,"49347":25837,"49348":25986,"49349":25987,"49350":26329,"49351":26326,"49352":27264,"49353":27284,"49354":27268,"49355":27298,"49356":27292,"49357":27355,"49358":27299,"49359":27262,"49360":27287,"49361":27280,"49362":27296,"49363":27484,"49364":27566,"49365":27610,"49366":27656,"49367":28632,"49368":28657,"49369":28639,"49370":28640,"49371":28635,"49372":28644,"49373":28651,"49374":28655,"49375":28544,"49376":28652,"49377":28641,"49378":28649,"49379":28629,"49380":28654,"49381":28656,"49382":29159,"49383":29151,"49384":29166,"49385":29158,"49386":29157,"49387":29165,"49388":29164,"49389":29172,"49390":29152,"49391":29237,"49392":29254,"49393":29552,"49394":29554,"49395":29865,"49396":29872,"49397":29862,"49398":29864,"49399":30278,"49400":30274,"49401":30284,"49402":30442,"49403":30643,"49404":30634,"49405":30640,"49406":30636,"49472":30631,"49473":30637,"49474":30703,"49475":30967,"49476":30970,"49477":30964,"49478":30959,"49479":30977,"49480":31143,"49481":31146,"49482":31319,"49483":31423,"49484":31751,"49485":31757,"49486":31742,"49487":31735,"49488":31756,"49489":31712,"49490":31968,"49491":31964,"49492":31966,"49493":31970,"49494":31967,"49495":31961,"49496":31965,"49497":32302,"49498":32318,"49499":32326,"49500":32311,"49501":32306,"49502":32323,"49503":32299,"49504":32317,"49505":32305,"49506":32325,"49507":32321,"49508":32308,"49509":32313,"49510":32328,"49511":32309,"49512":32319,"49513":32303,"49514":32580,"49515":32755,"49516":32764,"49517":32881,"49518":32882,"49519":32880,"49520":32879,"49521":32883,"49522":33222,"49523":33219,"49524":33210,"49525":33218,"49526":33216,"49527":33215,"49528":33213,"49529":33225,"49530":33214,"49531":33256,"49532":33289,"49533":33393,"49534":34218,"49569":34180,"49570":34174,"49571":34204,"49572":34193,"49573":34196,"49574":34223,"49575":34203,"49576":34183,"49577":34216,"49578":34186,"49579":34407,"49580":34752,"49581":34769,"49582":34739,"49583":34770,"49584":34758,"49585":34731,"49586":34747,"49587":34746,"49588":34760,"49589":34763,"49590":35131,"49591":35126,"49592":35140,"49593":35128,"49594":35133,"49595":35244,"49596":35598,"49597":35607,"49598":35609,"49599":35611,"49600":35594,"49601":35616,"49602":35613,"49603":35588,"49604":35600,"49605":35905,"49606":35903,"49607":35955,"49608":36090,"49609":36093,"49610":36092,"49611":36088,"49612":36091,"49613":36264,"49614":36425,"49615":36427,"49616":36424,"49617":36426,"49618":36676,"49619":36670,"49620":36674,"49621":36677,"49622":36671,"49623":36991,"49624":36989,"49625":36996,"49626":36993,"49627":36994,"49628":36992,"49629":37177,"49630":37283,"49631":37278,"49632":37276,"49633":37709,"49634":37762,"49635":37672,"49636":37749,"49637":37706,"49638":37733,"49639":37707,"49640":37656,"49641":37758,"49642":37740,"49643":37723,"49644":37744,"49645":37722,"49646":37716,"49647":38346,"49648":38347,"49649":38348,"49650":38344,"49651":38342,"49652":38577,"49653":38584,"49654":38614,"49655":38684,"49656":38686,"49657":38816,"49658":38867,"49659":38982,"49660":39094,"49661":39221,"49662":39425,"49728":39423,"49729":39854,"49730":39851,"49731":39850,"49732":39853,"49733":40251,"49734":40255,"49735":40587,"49736":40655,"49737":40670,"49738":40668,"49739":40669,"49740":40667,"49741":40766,"49742":40779,"49743":21474,"49744":22165,"49745":22190,"49746":22745,"49747":22744,"49748":23352,"49749":24413,"49750":25059,"49751":25139,"49752":25844,"49753":25842,"49754":25854,"49755":25862,"49756":25850,"49757":25851,"49758":25847,"49759":26039,"49760":26332,"49761":26406,"49762":27315,"49763":27308,"49764":27331,"49765":27323,"49766":27320,"49767":27330,"49768":27310,"49769":27311,"49770":27487,"49771":27512,"49772":27567,"49773":28681,"49774":28683,"49775":28670,"49776":28678,"49777":28666,"49778":28689,"49779":28687,"49780":29179,"49781":29180,"49782":29182,"49783":29176,"49784":29559,"49785":29557,"49786":29863,"49787":29887,"49788":29973,"49789":30294,"49790":30296,"49825":30290,"49826":30653,"49827":30655,"49828":30651,"49829":30652,"49830":30990,"49831":31150,"49832":31329,"49833":31330,"49834":31328,"49835":31428,"49836":31429,"49837":31787,"49838":31783,"49839":31786,"49840":31774,"49841":31779,"49842":31777,"49843":31975,"49844":32340,"49845":32341,"49846":32350,"49847":32346,"49848":32353,"49849":32338,"49850":32345,"49851":32584,"49852":32761,"49853":32763,"49854":32887,"49855":32886,"49856":33229,"49857":33231,"49858":33290,"49859":34255,"49860":34217,"49861":34253,"49862":34256,"49863":34249,"49864":34224,"49865":34234,"49866":34233,"49867":34214,"49868":34799,"49869":34796,"49870":34802,"49871":34784,"49872":35206,"49873":35250,"49874":35316,"49875":35624,"49876":35641,"49877":35628,"49878":35627,"49879":35920,"49880":36101,"49881":36441,"49882":36451,"49883":36454,"49884":36452,"49885":36447,"49886":36437,"49887":36544,"49888":36681,"49889":36685,"49890":36999,"49891":36995,"49892":37000,"49893":37291,"49894":37292,"49895":37328,"49896":37780,"49897":37770,"49898":37782,"49899":37794,"49900":37811,"49901":37806,"49902":37804,"49903":37808,"49904":37784,"49905":37786,"49906":37783,"49907":38356,"49908":38358,"49909":38352,"49910":38357,"49911":38626,"49912":38620,"49913":38617,"49914":38619,"49915":38622,"49916":38692,"49917":38819,"49918":38822,"49984":38829,"49985":38905,"49986":38989,"49987":38991,"49988":38988,"49989":38990,"49990":38995,"49991":39098,"49992":39230,"49993":39231,"49994":39229,"49995":39214,"49996":39333,"49997":39438,"49998":39617,"49999":39683,"50000":39686,"50001":39759,"50002":39758,"50003":39757,"50004":39882,"50005":39881,"50006":39933,"50007":39880,"50008":39872,"50009":40273,"50010":40285,"50011":40288,"50012":40672,"50013":40725,"50014":40748,"50015":20787,"50016":22181,"50017":22750,"50018":22751,"50019":22754,"50020":23541,"50021":40848,"50022":24300,"50023":25074,"50024":25079,"50025":25078,"50026":25077,"50027":25856,"50028":25871,"50029":26336,"50030":26333,"50031":27365,"50032":27357,"50033":27354,"50034":27347,"50035":28699,"50036":28703,"50037":28712,"50038":28698,"50039":28701,"50040":28693,"50041":28696,"50042":29190,"50043":29197,"50044":29272,"50045":29346,"50046":29560,"50081":29562,"50082":29885,"50083":29898,"50084":29923,"50085":30087,"50086":30086,"50087":30303,"50088":30305,"50089":30663,"50090":31001,"50091":31153,"50092":31339,"50093":31337,"50094":31806,"50095":31807,"50096":31800,"50097":31805,"50098":31799,"50099":31808,"50100":32363,"50101":32365,"50102":32377,"50103":32361,"50104":32362,"50105":32645,"50106":32371,"50107":32694,"50108":32697,"50109":32696,"50110":33240,"50111":34281,"50112":34269,"50113":34282,"50114":34261,"50115":34276,"50116":34277,"50117":34295,"50118":34811,"50119":34821,"50120":34829,"50121":34809,"50122":34814,"50123":35168,"50124":35167,"50125":35158,"50126":35166,"50127":35649,"50128":35676,"50129":35672,"50130":35657,"50131":35674,"50132":35662,"50133":35663,"50134":35654,"50135":35673,"50136":36104,"50137":36106,"50138":36476,"50139":36466,"50140":36487,"50141":36470,"50142":36460,"50143":36474,"50144":36468,"50145":36692,"50146":36686,"50147":36781,"50148":37002,"50149":37003,"50150":37297,"50151":37294,"50152":37857,"50153":37841,"50154":37855,"50155":37827,"50156":37832,"50157":37852,"50158":37853,"50159":37846,"50160":37858,"50161":37837,"50162":37848,"50163":37860,"50164":37847,"50165":37864,"50166":38364,"50167":38580,"50168":38627,"50169":38698,"50170":38695,"50171":38753,"50172":38876,"50173":38907,"50174":39006,"50240":39000,"50241":39003,"50242":39100,"50243":39237,"50244":39241,"50245":39446,"50246":39449,"50247":39693,"50248":39912,"50249":39911,"50250":39894,"50251":39899,"50252":40329,"50253":40289,"50254":40306,"50255":40298,"50256":40300,"50257":40594,"50258":40599,"50259":40595,"50260":40628,"50261":21240,"50262":22184,"50263":22199,"50264":22198,"50265":22196,"50266":22204,"50267":22756,"50268":23360,"50269":23363,"50270":23421,"50271":23542,"50272":24009,"50273":25080,"50274":25082,"50275":25880,"50276":25876,"50277":25881,"50278":26342,"50279":26407,"50280":27372,"50281":28734,"50282":28720,"50283":28722,"50284":29200,"50285":29563,"50286":29903,"50287":30306,"50288":30309,"50289":31014,"50290":31018,"50291":31020,"50292":31019,"50293":31431,"50294":31478,"50295":31820,"50296":31811,"50297":31821,"50298":31983,"50299":31984,"50300":36782,"50301":32381,"50302":32380,"50337":32386,"50338":32588,"50339":32768,"50340":33242,"50341":33382,"50342":34299,"50343":34297,"50344":34321,"50345":34298,"50346":34310,"50347":34315,"50348":34311,"50349":34314,"50350":34836,"50351":34837,"50352":35172,"50353":35258,"50354":35320,"50355":35696,"50356":35692,"50357":35686,"50358":35695,"50359":35679,"50360":35691,"50361":36111,"50362":36109,"50363":36489,"50364":36481,"50365":36485,"50366":36482,"50367":37300,"50368":37323,"50369":37912,"50370":37891,"50371":37885,"50372":38369,"50373":38704,"50374":39108,"50375":39250,"50376":39249,"50377":39336,"50378":39467,"50379":39472,"50380":39479,"50381":39477,"50382":39955,"50383":39949,"50384":40569,"50385":40629,"50386":40680,"50387":40751,"50388":40799,"50389":40803,"50390":40801,"50391":20791,"50392":20792,"50393":22209,"50394":22208,"50395":22210,"50396":22804,"50397":23660,"50398":24013,"50399":25084,"50400":25086,"50401":25885,"50402":25884,"50403":26005,"50404":26345,"50405":27387,"50406":27396,"50407":27386,"50408":27570,"50409":28748,"50410":29211,"50411":29351,"50412":29910,"50413":29908,"50414":30313,"50415":30675,"50416":31824,"50417":32399,"50418":32396,"50419":32700,"50420":34327,"50421":34349,"50422":34330,"50423":34851,"50424":34850,"50425":34849,"50426":34847,"50427":35178,"50428":35180,"50429":35261,"50430":35700,"50496":35703,"50497":35709,"50498":36115,"50499":36490,"50500":36493,"50501":36491,"50502":36703,"50503":36783,"50504":37306,"50505":37934,"50506":37939,"50507":37941,"50508":37946,"50509":37944,"50510":37938,"50511":37931,"50512":38370,"50513":38712,"50514":38713,"50515":38706,"50516":38911,"50517":39015,"50518":39013,"50519":39255,"50520":39493,"50521":39491,"50522":39488,"50523":39486,"50524":39631,"50525":39764,"50526":39761,"50527":39981,"50528":39973,"50529":40367,"50530":40372,"50531":40386,"50532":40376,"50533":40605,"50534":40687,"50535":40729,"50536":40796,"50537":40806,"50538":40807,"50539":20796,"50540":20795,"50541":22216,"50542":22218,"50543":22217,"50544":23423,"50545":24020,"50546":24018,"50547":24398,"50548":25087,"50549":25892,"50550":27402,"50551":27489,"50552":28753,"50553":28760,"50554":29568,"50555":29924,"50556":30090,"50557":30318,"50558":30316,"50593":31155,"50594":31840,"50595":31839,"50596":32894,"50597":32893,"50598":33247,"50599":35186,"50600":35183,"50601":35324,"50602":35712,"50603":36118,"50604":36119,"50605":36497,"50606":36499,"50607":36705,"50608":37192,"50609":37956,"50610":37969,"50611":37970,"50612":38717,"50613":38718,"50614":38851,"50615":38849,"50616":39019,"50617":39253,"50618":39509,"50619":39501,"50620":39634,"50621":39706,"50622":40009,"50623":39985,"50624":39998,"50625":39995,"50626":40403,"50627":40407,"50628":40756,"50629":40812,"50630":40810,"50631":40852,"50632":22220,"50633":24022,"50634":25088,"50635":25891,"50636":25899,"50637":25898,"50638":26348,"50639":27408,"50640":29914,"50641":31434,"50642":31844,"50643":31843,"50644":31845,"50645":32403,"50646":32406,"50647":32404,"50648":33250,"50649":34360,"50650":34367,"50651":34865,"50652":35722,"50653":37008,"50654":37007,"50655":37987,"50656":37984,"50657":37988,"50658":38760,"50659":39023,"50660":39260,"50661":39514,"50662":39515,"50663":39511,"50664":39635,"50665":39636,"50666":39633,"50667":40020,"50668":40023,"50669":40022,"50670":40421,"50671":40607,"50672":40692,"50673":22225,"50674":22761,"50675":25900,"50676":28766,"50677":30321,"50678":30322,"50679":30679,"50680":32592,"50681":32648,"50682":34870,"50683":34873,"50684":34914,"50685":35731,"50686":35730,"50752":35734,"50753":33399,"50754":36123,"50755":37312,"50756":37994,"50757":38722,"50758":38728,"50759":38724,"50760":38854,"50761":39024,"50762":39519,"50763":39714,"50764":39768,"50765":40031,"50766":40441,"50767":40442,"50768":40572,"50769":40573,"50770":40711,"50771":40823,"50772":40818,"50773":24307,"50774":27414,"50775":28771,"50776":31852,"50777":31854,"50778":34875,"50779":35264,"50780":36513,"50781":37313,"50782":38002,"50783":38000,"50784":39025,"50785":39262,"50786":39638,"50787":39715,"50788":40652,"50789":28772,"50790":30682,"50791":35738,"50792":38007,"50793":38857,"50794":39522,"50795":39525,"50796":32412,"50797":35740,"50798":36522,"50799":37317,"50800":38013,"50801":38014,"50802":38012,"50803":40055,"50804":40056,"50805":40695,"50806":35924,"50807":38015,"50808":40474,"50809":29224,"50810":39530,"50811":39729,"50812":40475,"50813":40478,"50814":31858,"50849":9312,"50850":9313,"50851":9314,"50852":9315,"50853":9316,"50854":9317,"50855":9318,"50856":9319,"50857":9320,"50858":9321,"50859":9332,"50860":9333,"50861":9334,"50862":9335,"50863":9336,"50864":9337,"50865":9338,"50866":9339,"50867":9340,"50868":9341,"50869":8560,"50870":8561,"50871":8562,"50872":8563,"50873":8564,"50874":8565,"50875":8566,"50876":8567,"50877":8568,"50878":8569,"50879":20022,"50880":20031,"50881":20101,"50882":20128,"50883":20866,"50884":20886,"50885":20907,"50886":21241,"50887":21304,"50888":21353,"50889":21430,"50890":22794,"50891":23424,"50892":24027,"50893":24186,"50894":24191,"50895":24308,"50896":24400,"50897":24417,"50898":25908,"50899":26080,"50900":30098,"50901":30326,"50902":36789,"50903":38582,"50904":168,"50905":710,"50906":12541,"50907":12542,"50908":12445,"50909":12446,"50910":12291,"50911":20189,"50912":12293,"50913":12294,"50914":12295,"50915":12540,"50916":65339,"50917":65341,"50918":10045,"50919":12353,"50920":12354,"50921":12355,"50922":12356,"50923":12357,"50924":12358,"50925":12359,"50926":12360,"50927":12361,"50928":12362,"50929":12363,"50930":12364,"50931":12365,"50932":12366,"50933":12367,"50934":12368,"50935":12369,"50936":12370,"50937":12371,"50938":12372,"50939":12373,"50940":12374,"50941":12375,"50942":12376,"51008":12377,"51009":12378,"51010":12379,"51011":12380,"51012":12381,"51013":12382,"51014":12383,"51015":12384,"51016":12385,"51017":12386,"51018":12387,"51019":12388,"51020":12389,"51021":12390,"51022":12391,"51023":12392,"51024":12393,"51025":12394,"51026":12395,"51027":12396,"51028":12397,"51029":12398,"51030":12399,"51031":12400,"51032":12401,"51033":12402,"51034":12403,"51035":12404,"51036":12405,"51037":12406,"51038":12407,"51039":12408,"51040":12409,"51041":12410,"51042":12411,"51043":12412,"51044":12413,"51045":12414,"51046":12415,"51047":12416,"51048":12417,"51049":12418,"51050":12419,"51051":12420,"51052":12421,"51053":12422,"51054":12423,"51055":12424,"51056":12425,"51057":12426,"51058":12427,"51059":12428,"51060":12429,"51061":12430,"51062":12431,"51063":12432,"51064":12433,"51065":12434,"51066":12435,"51067":12449,"51068":12450,"51069":12451,"51070":12452,"51105":12453,"51106":12454,"51107":12455,"51108":12456,"51109":12457,"51110":12458,"51111":12459,"51112":12460,"51113":12461,"51114":12462,"51115":12463,"51116":12464,"51117":12465,"51118":12466,"51119":12467,"51120":12468,"51121":12469,"51122":12470,"51123":12471,"51124":12472,"51125":12473,"51126":12474,"51127":12475,"51128":12476,"51129":12477,"51130":12478,"51131":12479,"51132":12480,"51133":12481,"51134":12482,"51135":12483,"51136":12484,"51137":12485,"51138":12486,"51139":12487,"51140":12488,"51141":12489,"51142":12490,"51143":12491,"51144":12492,"51145":12493,"51146":12494,"51147":12495,"51148":12496,"51149":12497,"51150":12498,"51151":12499,"51152":12500,"51153":12501,"51154":12502,"51155":12503,"51156":12504,"51157":12505,"51158":12506,"51159":12507,"51160":12508,"51161":12509,"51162":12510,"51163":12511,"51164":12512,"51165":12513,"51166":12514,"51167":12515,"51168":12516,"51169":12517,"51170":12518,"51171":12519,"51172":12520,"51173":12521,"51174":12522,"51175":12523,"51176":12524,"51177":12525,"51178":12526,"51179":12527,"51180":12528,"51181":12529,"51182":12530,"51183":12531,"51184":12532,"51185":12533,"51186":12534,"51187":1040,"51188":1041,"51189":1042,"51190":1043,"51191":1044,"51192":1045,"51193":1025,"51194":1046,"51195":1047,"51196":1048,"51197":1049,"51198":1050,"51264":1051,"51265":1052,"51266":1053,"51267":1054,"51268":1055,"51269":1056,"51270":1057,"51271":1058,"51272":1059,"51273":1060,"51274":1061,"51275":1062,"51276":1063,"51277":1064,"51278":1065,"51279":1066,"51280":1067,"51281":1068,"51282":1069,"51283":1070,"51284":1071,"51285":1072,"51286":1073,"51287":1074,"51288":1075,"51289":1076,"51290":1077,"51291":1105,"51292":1078,"51293":1079,"51294":1080,"51295":1081,"51296":1082,"51297":1083,"51298":1084,"51299":1085,"51300":1086,"51301":1087,"51302":1088,"51303":1089,"51304":1090,"51305":1091,"51306":1092,"51307":1093,"51308":1094,"51309":1095,"51310":1096,"51311":1097,"51312":1098,"51313":1099,"51314":1100,"51315":1101,"51316":1102,"51317":1103,"51318":8679,"51319":8632,"51320":8633,"51321":12751,"51322":63462,"51323":20058,"51324":63464,"51325":20994,"51326":17553,"51361":40880,"51362":20872,"51363":40881,"51364":63470,"51365":63471,"51366":63472,"51367":63473,"51368":63474,"51369":63475,"51370":63476,"51371":63477,"51372":63478,"51373":63479,"51374":63480,"51375":63481,"51376":63482,"51377":12443,"51378":12444,"51379":12436,"51380":12535,"51381":12536,"51382":12537,"51383":12538,"51384":12539,"51385":65377,"51386":65378,"51387":65379,"51388":65380,"51389":65381,"51390":65382,"51391":65383,"51392":65384,"51393":65385,"51394":65386,"51395":65387,"51396":65388,"51397":65389,"51398":65390,"51399":65391,"51400":65392,"51401":65393,"51402":65394,"51403":65395,"51404":65396,"51405":65506,"51406":65508,"51407":65287,"51408":65282,"51409":12849,"51410":8470,"51411":8481,"51412":65397,"51413":65398,"51414":65399,"51415":65400,"51416":65401,"51417":65402,"51418":65403,"51419":65404,"51420":65405,"51421":65406,"51422":65407,"51423":65408,"51424":65409,"51425":65410,"51426":65411,"51427":65412,"51428":65413,"51429":65414,"51430":65415,"51431":65416,"51432":65417,"51433":65418,"51434":65419,"51435":65420,"51436":65421,"51437":65422,"51438":65423,"51439":65424,"51440":65425,"51441":65426,"51442":65427,"51443":65428,"51444":65429,"51445":65430,"51446":65431,"51447":65432,"51448":65433,"51449":65434,"51450":65435,"51451":65436,"51452":65437,"51453":65438,"51454":65439,"51520":20034,"51521":20060,"51522":20981,"51523":21274,"51524":21378,"51525":19975,"51526":19980,"51527":20039,"51528":20109,"51529":22231,"51530":64012,"51531":23662,"51532":24435,"51533":19983,"51534":20871,"51535":19982,"51536":20014,"51537":20115,"51538":20162,"51539":20169,"51540":20168,"51541":20888,"51542":21244,"51543":21356,"51544":21433,"51545":22304,"51546":22787,"51547":22828,"51548":23568,"51549":24063,"51550":26081,"51551":27571,"51552":27596,"51553":27668,"51554":29247,"51555":20017,"51556":20028,"51557":20200,"51558":20188,"51559":20201,"51560":20193,"51561":20189,"51562":20186,"51563":21004,"51564":21276,"51565":21324,"51566":22306,"51567":22307,"51568":22807,"51569":22831,"51570":23425,"51571":23428,"51572":23570,"51573":23611,"51574":23668,"51575":23667,"51576":24068,"51577":24192,"51578":24194,"51579":24521,"51580":25097,"51581":25168,"51582":27669,"51617":27702,"51618":27715,"51619":27711,"51620":27707,"51621":29358,"51622":29360,"51623":29578,"51624":31160,"51625":32906,"51626":38430,"51627":20238,"51628":20248,"51629":20268,"51630":20213,"51631":20244,"51632":20209,"51633":20224,"51634":20215,"51635":20232,"51636":20253,"51637":20226,"51638":20229,"51639":20258,"51640":20243,"51641":20228,"51642":20212,"51643":20242,"51644":20913,"51645":21011,"51646":21001,"51647":21008,"51648":21158,"51649":21282,"51650":21279,"51651":21325,"51652":21386,"51653":21511,"51654":22241,"51655":22239,"51656":22318,"51657":22314,"51658":22324,"51659":22844,"51660":22912,"51661":22908,"51662":22917,"51663":22907,"51664":22910,"51665":22903,"51666":22911,"51667":23382,"51668":23573,"51669":23589,"51670":23676,"51671":23674,"51672":23675,"51673":23678,"51674":24031,"51675":24181,"51676":24196,"51677":24322,"51678":24346,"51679":24436,"51680":24533,"51681":24532,"51682":24527,"51683":25180,"51684":25182,"51685":25188,"51686":25185,"51687":25190,"51688":25186,"51689":25177,"51690":25184,"51691":25178,"51692":25189,"51693":26095,"51694":26094,"51695":26430,"51696":26425,"51697":26424,"51698":26427,"51699":26426,"51700":26431,"51701":26428,"51702":26419,"51703":27672,"51704":27718,"51705":27730,"51706":27740,"51707":27727,"51708":27722,"51709":27732,"51710":27723,"51776":27724,"51777":28785,"51778":29278,"51779":29364,"51780":29365,"51781":29582,"51782":29994,"51783":30335,"51784":31349,"51785":32593,"51786":33400,"51787":33404,"51788":33408,"51789":33405,"51790":33407,"51791":34381,"51792":35198,"51793":37017,"51794":37015,"51795":37016,"51796":37019,"51797":37012,"51798":38434,"51799":38436,"51800":38432,"51801":38435,"51802":20310,"51803":20283,"51804":20322,"51805":20297,"51806":20307,"51807":20324,"51808":20286,"51809":20327,"51810":20306,"51811":20319,"51812":20289,"51813":20312,"51814":20269,"51815":20275,"51816":20287,"51817":20321,"51818":20879,"51819":20921,"51820":21020,"51821":21022,"51822":21025,"51823":21165,"51824":21166,"51825":21257,"51826":21347,"51827":21362,"51828":21390,"51829":21391,"51830":21552,"51831":21559,"51832":21546,"51833":21588,"51834":21573,"51835":21529,"51836":21532,"51837":21541,"51838":21528,"51873":21565,"51874":21583,"51875":21569,"51876":21544,"51877":21540,"51878":21575,"51879":22254,"51880":22247,"51881":22245,"51882":22337,"51883":22341,"51884":22348,"51885":22345,"51886":22347,"51887":22354,"51888":22790,"51889":22848,"51890":22950,"51891":22936,"51892":22944,"51893":22935,"51894":22926,"51895":22946,"51896":22928,"51897":22927,"51898":22951,"51899":22945,"51900":23438,"51901":23442,"51902":23592,"51903":23594,"51904":23693,"51905":23695,"51906":23688,"51907":23691,"51908":23689,"51909":23698,"51910":23690,"51911":23686,"51912":23699,"51913":23701,"51914":24032,"51915":24074,"51916":24078,"51917":24203,"51918":24201,"51919":24204,"51920":24200,"51921":24205,"51922":24325,"51923":24349,"51924":24440,"51925":24438,"51926":24530,"51927":24529,"51928":24528,"51929":24557,"51930":24552,"51931":24558,"51932":24563,"51933":24545,"51934":24548,"51935":24547,"51936":24570,"51937":24559,"51938":24567,"51939":24571,"51940":24576,"51941":24564,"51942":25146,"51943":25219,"51944":25228,"51945":25230,"51946":25231,"51947":25236,"51948":25223,"51949":25201,"51950":25211,"51951":25210,"51952":25200,"51953":25217,"51954":25224,"51955":25207,"51956":25213,"51957":25202,"51958":25204,"51959":25911,"51960":26096,"51961":26100,"51962":26099,"51963":26098,"51964":26101,"51965":26437,"51966":26439,"52032":26457,"52033":26453,"52034":26444,"52035":26440,"52036":26461,"52037":26445,"52038":26458,"52039":26443,"52040":27600,"52041":27673,"52042":27674,"52043":27768,"52044":27751,"52045":27755,"52046":27780,"52047":27787,"52048":27791,"52049":27761,"52050":27759,"52051":27753,"52052":27802,"52053":27757,"52054":27783,"52055":27797,"52056":27804,"52057":27750,"52058":27763,"52059":27749,"52060":27771,"52061":27790,"52062":28788,"52063":28794,"52064":29283,"52065":29375,"52066":29373,"52067":29379,"52068":29382,"52069":29377,"52070":29370,"52071":29381,"52072":29589,"52073":29591,"52074":29587,"52075":29588,"52076":29586,"52077":30010,"52078":30009,"52079":30100,"52080":30101,"52081":30337,"52082":31037,"52083":32820,"52084":32917,"52085":32921,"52086":32912,"52087":32914,"52088":32924,"52089":33424,"52090":33423,"52091":33413,"52092":33422,"52093":33425,"52094":33427,"52129":33418,"52130":33411,"52131":33412,"52132":35960,"52133":36809,"52134":36799,"52135":37023,"52136":37025,"52137":37029,"52138":37022,"52139":37031,"52140":37024,"52141":38448,"52142":38440,"52143":38447,"52144":38445,"52145":20019,"52146":20376,"52147":20348,"52148":20357,"52149":20349,"52150":20352,"52151":20359,"52152":20342,"52153":20340,"52154":20361,"52155":20356,"52156":20343,"52157":20300,"52158":20375,"52159":20330,"52160":20378,"52161":20345,"52162":20353,"52163":20344,"52164":20368,"52165":20380,"52166":20372,"52167":20382,"52168":20370,"52169":20354,"52170":20373,"52171":20331,"52172":20334,"52173":20894,"52174":20924,"52175":20926,"52176":21045,"52177":21042,"52178":21043,"52179":21062,"52180":21041,"52181":21180,"52182":21258,"52183":21259,"52184":21308,"52185":21394,"52186":21396,"52187":21639,"52188":21631,"52189":21633,"52190":21649,"52191":21634,"52192":21640,"52193":21611,"52194":21626,"52195":21630,"52196":21605,"52197":21612,"52198":21620,"52199":21606,"52200":21645,"52201":21615,"52202":21601,"52203":21600,"52204":21656,"52205":21603,"52206":21607,"52207":21604,"52208":22263,"52209":22265,"52210":22383,"52211":22386,"52212":22381,"52213":22379,"52214":22385,"52215":22384,"52216":22390,"52217":22400,"52218":22389,"52219":22395,"52220":22387,"52221":22388,"52222":22370,"52288":22376,"52289":22397,"52290":22796,"52291":22853,"52292":22965,"52293":22970,"52294":22991,"52295":22990,"52296":22962,"52297":22988,"52298":22977,"52299":22966,"52300":22972,"52301":22979,"52302":22998,"52303":22961,"52304":22973,"52305":22976,"52306":22984,"52307":22964,"52308":22983,"52309":23394,"52310":23397,"52311":23443,"52312":23445,"52313":23620,"52314":23623,"52315":23726,"52316":23716,"52317":23712,"52318":23733,"52319":23727,"52320":23720,"52321":23724,"52322":23711,"52323":23715,"52324":23725,"52325":23714,"52326":23722,"52327":23719,"52328":23709,"52329":23717,"52330":23734,"52331":23728,"52332":23718,"52333":24087,"52334":24084,"52335":24089,"52336":24360,"52337":24354,"52338":24355,"52339":24356,"52340":24404,"52341":24450,"52342":24446,"52343":24445,"52344":24542,"52345":24549,"52346":24621,"52347":24614,"52348":24601,"52349":24626,"52350":24587,"52385":24628,"52386":24586,"52387":24599,"52388":24627,"52389":24602,"52390":24606,"52391":24620,"52392":24610,"52393":24589,"52394":24592,"52395":24622,"52396":24595,"52397":24593,"52398":24588,"52399":24585,"52400":24604,"52401":25108,"52402":25149,"52403":25261,"52404":25268,"52405":25297,"52406":25278,"52407":25258,"52408":25270,"52409":25290,"52410":25262,"52411":25267,"52412":25263,"52413":25275,"52414":25257,"52415":25264,"52416":25272,"52417":25917,"52418":26024,"52419":26043,"52420":26121,"52421":26108,"52422":26116,"52423":26130,"52424":26120,"52425":26107,"52426":26115,"52427":26123,"52428":26125,"52429":26117,"52430":26109,"52431":26129,"52432":26128,"52433":26358,"52434":26378,"52435":26501,"52436":26476,"52437":26510,"52438":26514,"52439":26486,"52440":26491,"52441":26520,"52442":26502,"52443":26500,"52444":26484,"52445":26509,"52446":26508,"52447":26490,"52448":26527,"52449":26513,"52450":26521,"52451":26499,"52452":26493,"52453":26497,"52454":26488,"52455":26489,"52456":26516,"52457":27429,"52458":27520,"52459":27518,"52460":27614,"52461":27677,"52462":27795,"52463":27884,"52464":27883,"52465":27886,"52466":27865,"52467":27830,"52468":27860,"52469":27821,"52470":27879,"52471":27831,"52472":27856,"52473":27842,"52474":27834,"52475":27843,"52476":27846,"52477":27885,"52478":27890,"52544":27858,"52545":27869,"52546":27828,"52547":27786,"52548":27805,"52549":27776,"52550":27870,"52551":27840,"52552":27952,"52553":27853,"52554":27847,"52555":27824,"52556":27897,"52557":27855,"52558":27881,"52559":27857,"52560":28820,"52561":28824,"52562":28805,"52563":28819,"52564":28806,"52565":28804,"52566":28817,"52567":28822,"52568":28802,"52569":28826,"52570":28803,"52571":29290,"52572":29398,"52573":29387,"52574":29400,"52575":29385,"52576":29404,"52577":29394,"52578":29396,"52579":29402,"52580":29388,"52581":29393,"52582":29604,"52583":29601,"52584":29613,"52585":29606,"52586":29602,"52587":29600,"52588":29612,"52589":29597,"52590":29917,"52591":29928,"52592":30015,"52593":30016,"52594":30014,"52595":30092,"52596":30104,"52597":30383,"52598":30451,"52599":30449,"52600":30448,"52601":30453,"52602":30712,"52603":30716,"52604":30713,"52605":30715,"52606":30714,"52641":30711,"52642":31042,"52643":31039,"52644":31173,"52645":31352,"52646":31355,"52647":31483,"52648":31861,"52649":31997,"52650":32821,"52651":32911,"52652":32942,"52653":32931,"52654":32952,"52655":32949,"52656":32941,"52657":33312,"52658":33440,"52659":33472,"52660":33451,"52661":33434,"52662":33432,"52663":33435,"52664":33461,"52665":33447,"52666":33454,"52667":33468,"52668":33438,"52669":33466,"52670":33460,"52671":33448,"52672":33441,"52673":33449,"52674":33474,"52675":33444,"52676":33475,"52677":33462,"52678":33442,"52679":34416,"52680":34415,"52681":34413,"52682":34414,"52683":35926,"52684":36818,"52685":36811,"52686":36819,"52687":36813,"52688":36822,"52689":36821,"52690":36823,"52691":37042,"52692":37044,"52693":37039,"52694":37043,"52695":37040,"52696":38457,"52697":38461,"52698":38460,"52699":38458,"52700":38467,"52701":20429,"52702":20421,"52703":20435,"52704":20402,"52705":20425,"52706":20427,"52707":20417,"52708":20436,"52709":20444,"52710":20441,"52711":20411,"52712":20403,"52713":20443,"52714":20423,"52715":20438,"52716":20410,"52717":20416,"52718":20409,"52719":20460,"52720":21060,"52721":21065,"52722":21184,"52723":21186,"52724":21309,"52725":21372,"52726":21399,"52727":21398,"52728":21401,"52729":21400,"52730":21690,"52731":21665,"52732":21677,"52733":21669,"52734":21711,"52800":21699,"52801":33549,"52802":21687,"52803":21678,"52804":21718,"52805":21686,"52806":21701,"52807":21702,"52808":21664,"52809":21616,"52810":21692,"52811":21666,"52812":21694,"52813":21618,"52814":21726,"52815":21680,"52816":22453,"52817":22430,"52818":22431,"52819":22436,"52820":22412,"52821":22423,"52822":22429,"52823":22427,"52824":22420,"52825":22424,"52826":22415,"52827":22425,"52828":22437,"52829":22426,"52830":22421,"52831":22772,"52832":22797,"52833":22867,"52834":23009,"52835":23006,"52836":23022,"52837":23040,"52838":23025,"52839":23005,"52840":23034,"52841":23037,"52842":23036,"52843":23030,"52844":23012,"52845":23026,"52846":23031,"52847":23003,"52848":23017,"52849":23027,"52850":23029,"52851":23008,"52852":23038,"52853":23028,"52854":23021,"52855":23464,"52856":23628,"52857":23760,"52858":23768,"52859":23756,"52860":23767,"52861":23755,"52862":23771,"52897":23774,"52898":23770,"52899":23753,"52900":23751,"52901":23754,"52902":23766,"52903":23763,"52904":23764,"52905":23759,"52906":23752,"52907":23750,"52908":23758,"52909":23775,"52910":23800,"52911":24057,"52912":24097,"52913":24098,"52914":24099,"52915":24096,"52916":24100,"52917":24240,"52918":24228,"52919":24226,"52920":24219,"52921":24227,"52922":24229,"52923":24327,"52924":24366,"52925":24406,"52926":24454,"52927":24631,"52928":24633,"52929":24660,"52930":24690,"52931":24670,"52932":24645,"52933":24659,"52934":24647,"52935":24649,"52936":24667,"52937":24652,"52938":24640,"52939":24642,"52940":24671,"52941":24612,"52942":24644,"52943":24664,"52944":24678,"52945":24686,"52946":25154,"52947":25155,"52948":25295,"52949":25357,"52950":25355,"52951":25333,"52952":25358,"52953":25347,"52954":25323,"52955":25337,"52956":25359,"52957":25356,"52958":25336,"52959":25334,"52960":25344,"52961":25363,"52962":25364,"52963":25338,"52964":25365,"52965":25339,"52966":25328,"52967":25921,"52968":25923,"52969":26026,"52970":26047,"52971":26166,"52972":26145,"52973":26162,"52974":26165,"52975":26140,"52976":26150,"52977":26146,"52978":26163,"52979":26155,"52980":26170,"52981":26141,"52982":26164,"52983":26169,"52984":26158,"52985":26383,"52986":26384,"52987":26561,"52988":26610,"52989":26568,"52990":26554,"53056":26588,"53057":26555,"53058":26616,"53059":26584,"53060":26560,"53061":26551,"53062":26565,"53063":26603,"53064":26596,"53065":26591,"53066":26549,"53067":26573,"53068":26547,"53069":26615,"53070":26614,"53071":26606,"53072":26595,"53073":26562,"53074":26553,"53075":26574,"53076":26599,"53077":26608,"53078":26546,"53079":26620,"53080":26566,"53081":26605,"53082":26572,"53083":26542,"53084":26598,"53085":26587,"53086":26618,"53087":26569,"53088":26570,"53089":26563,"53090":26602,"53091":26571,"53092":27432,"53093":27522,"53094":27524,"53095":27574,"53096":27606,"53097":27608,"53098":27616,"53099":27680,"53100":27681,"53101":27944,"53102":27956,"53103":27949,"53104":27935,"53105":27964,"53106":27967,"53107":27922,"53108":27914,"53109":27866,"53110":27955,"53111":27908,"53112":27929,"53113":27962,"53114":27930,"53115":27921,"53116":27904,"53117":27933,"53118":27970,"53153":27905,"53154":27928,"53155":27959,"53156":27907,"53157":27919,"53158":27968,"53159":27911,"53160":27936,"53161":27948,"53162":27912,"53163":27938,"53164":27913,"53165":27920,"53166":28855,"53167":28831,"53168":28862,"53169":28849,"53170":28848,"53171":28833,"53172":28852,"53173":28853,"53174":28841,"53175":29249,"53176":29257,"53177":29258,"53178":29292,"53179":29296,"53180":29299,"53181":29294,"53182":29386,"53183":29412,"53184":29416,"53185":29419,"53186":29407,"53187":29418,"53188":29414,"53189":29411,"53190":29573,"53191":29644,"53192":29634,"53193":29640,"53194":29637,"53195":29625,"53196":29622,"53197":29621,"53198":29620,"53199":29675,"53200":29631,"53201":29639,"53202":29630,"53203":29635,"53204":29638,"53205":29624,"53206":29643,"53207":29932,"53208":29934,"53209":29998,"53210":30023,"53211":30024,"53212":30119,"53213":30122,"53214":30329,"53215":30404,"53216":30472,"53217":30467,"53218":30468,"53219":30469,"53220":30474,"53221":30455,"53222":30459,"53223":30458,"53224":30695,"53225":30696,"53226":30726,"53227":30737,"53228":30738,"53229":30725,"53230":30736,"53231":30735,"53232":30734,"53233":30729,"53234":30723,"53235":30739,"53236":31050,"53237":31052,"53238":31051,"53239":31045,"53240":31044,"53241":31189,"53242":31181,"53243":31183,"53244":31190,"53245":31182,"53246":31360,"53312":31358,"53313":31441,"53314":31488,"53315":31489,"53316":31866,"53317":31864,"53318":31865,"53319":31871,"53320":31872,"53321":31873,"53322":32003,"53323":32008,"53324":32001,"53325":32600,"53326":32657,"53327":32653,"53328":32702,"53329":32775,"53330":32782,"53331":32783,"53332":32788,"53333":32823,"53334":32984,"53335":32967,"53336":32992,"53337":32977,"53338":32968,"53339":32962,"53340":32976,"53341":32965,"53342":32995,"53343":32985,"53344":32988,"53345":32970,"53346":32981,"53347":32969,"53348":32975,"53349":32983,"53350":32998,"53351":32973,"53352":33279,"53353":33313,"53354":33428,"53355":33497,"53356":33534,"53357":33529,"53358":33543,"53359":33512,"53360":33536,"53361":33493,"53362":33594,"53363":33515,"53364":33494,"53365":33524,"53366":33516,"53367":33505,"53368":33522,"53369":33525,"53370":33548,"53371":33531,"53372":33526,"53373":33520,"53374":33514,"53409":33508,"53410":33504,"53411":33530,"53412":33523,"53413":33517,"53414":34423,"53415":34420,"53416":34428,"53417":34419,"53418":34881,"53419":34894,"53420":34919,"53421":34922,"53422":34921,"53423":35283,"53424":35332,"53425":35335,"53426":36210,"53427":36835,"53428":36833,"53429":36846,"53430":36832,"53431":37105,"53432":37053,"53433":37055,"53434":37077,"53435":37061,"53436":37054,"53437":37063,"53438":37067,"53439":37064,"53440":37332,"53441":37331,"53442":38484,"53443":38479,"53444":38481,"53445":38483,"53446":38474,"53447":38478,"53448":20510,"53449":20485,"53450":20487,"53451":20499,"53452":20514,"53453":20528,"53454":20507,"53455":20469,"53456":20468,"53457":20531,"53458":20535,"53459":20524,"53460":20470,"53461":20471,"53462":20503,"53463":20508,"53464":20512,"53465":20519,"53466":20533,"53467":20527,"53468":20529,"53469":20494,"53470":20826,"53471":20884,"53472":20883,"53473":20938,"53474":20932,"53475":20933,"53476":20936,"53477":20942,"53478":21089,"53479":21082,"53480":21074,"53481":21086,"53482":21087,"53483":21077,"53484":21090,"53485":21197,"53486":21262,"53487":21406,"53488":21798,"53489":21730,"53490":21783,"53491":21778,"53492":21735,"53493":21747,"53494":21732,"53495":21786,"53496":21759,"53497":21764,"53498":21768,"53499":21739,"53500":21777,"53501":21765,"53502":21745,"53568":21770,"53569":21755,"53570":21751,"53571":21752,"53572":21728,"53573":21774,"53574":21763,"53575":21771,"53576":22273,"53577":22274,"53578":22476,"53579":22578,"53580":22485,"53581":22482,"53582":22458,"53583":22470,"53584":22461,"53585":22460,"53586":22456,"53587":22454,"53588":22463,"53589":22471,"53590":22480,"53591":22457,"53592":22465,"53593":22798,"53594":22858,"53595":23065,"53596":23062,"53597":23085,"53598":23086,"53599":23061,"53600":23055,"53601":23063,"53602":23050,"53603":23070,"53604":23091,"53605":23404,"53606":23463,"53607":23469,"53608":23468,"53609":23555,"53610":23638,"53611":23636,"53612":23788,"53613":23807,"53614":23790,"53615":23793,"53616":23799,"53617":23808,"53618":23801,"53619":24105,"53620":24104,"53621":24232,"53622":24238,"53623":24234,"53624":24236,"53625":24371,"53626":24368,"53627":24423,"53628":24669,"53629":24666,"53630":24679,"53665":24641,"53666":24738,"53667":24712,"53668":24704,"53669":24722,"53670":24705,"53671":24733,"53672":24707,"53673":24725,"53674":24731,"53675":24727,"53676":24711,"53677":24732,"53678":24718,"53679":25113,"53680":25158,"53681":25330,"53682":25360,"53683":25430,"53684":25388,"53685":25412,"53686":25413,"53687":25398,"53688":25411,"53689":25572,"53690":25401,"53691":25419,"53692":25418,"53693":25404,"53694":25385,"53695":25409,"53696":25396,"53697":25432,"53698":25428,"53699":25433,"53700":25389,"53701":25415,"53702":25395,"53703":25434,"53704":25425,"53705":25400,"53706":25431,"53707":25408,"53708":25416,"53709":25930,"53710":25926,"53711":26054,"53712":26051,"53713":26052,"53714":26050,"53715":26186,"53716":26207,"53717":26183,"53718":26193,"53719":26386,"53720":26387,"53721":26655,"53722":26650,"53723":26697,"53724":26674,"53725":26675,"53726":26683,"53727":26699,"53728":26703,"53729":26646,"53730":26673,"53731":26652,"53732":26677,"53733":26667,"53734":26669,"53735":26671,"53736":26702,"53737":26692,"53738":26676,"53739":26653,"53740":26642,"53741":26644,"53742":26662,"53743":26664,"53744":26670,"53745":26701,"53746":26682,"53747":26661,"53748":26656,"53749":27436,"53750":27439,"53751":27437,"53752":27441,"53753":27444,"53754":27501,"53755":32898,"53756":27528,"53757":27622,"53758":27620,"53824":27624,"53825":27619,"53826":27618,"53827":27623,"53828":27685,"53829":28026,"53830":28003,"53831":28004,"53832":28022,"53833":27917,"53834":28001,"53835":28050,"53836":27992,"53837":28002,"53838":28013,"53839":28015,"53840":28049,"53841":28045,"53842":28143,"53843":28031,"53844":28038,"53845":27998,"53846":28007,"53847":28000,"53848":28055,"53849":28016,"53850":28028,"53851":27999,"53852":28034,"53853":28056,"53854":27951,"53855":28008,"53856":28043,"53857":28030,"53858":28032,"53859":28036,"53860":27926,"53861":28035,"53862":28027,"53863":28029,"53864":28021,"53865":28048,"53866":28892,"53867":28883,"53868":28881,"53869":28893,"53870":28875,"53871":32569,"53872":28898,"53873":28887,"53874":28882,"53875":28894,"53876":28896,"53877":28884,"53878":28877,"53879":28869,"53880":28870,"53881":28871,"53882":28890,"53883":28878,"53884":28897,"53885":29250,"53886":29304,"53921":29303,"53922":29302,"53923":29440,"53924":29434,"53925":29428,"53926":29438,"53927":29430,"53928":29427,"53929":29435,"53930":29441,"53931":29651,"53932":29657,"53933":29669,"53934":29654,"53935":29628,"53936":29671,"53937":29667,"53938":29673,"53939":29660,"53940":29650,"53941":29659,"53942":29652,"53943":29661,"53944":29658,"53945":29655,"53946":29656,"53947":29672,"53948":29918,"53949":29919,"53950":29940,"53951":29941,"53952":29985,"53953":30043,"53954":30047,"53955":30128,"53956":30145,"53957":30139,"53958":30148,"53959":30144,"53960":30143,"53961":30134,"53962":30138,"53963":30346,"53964":30409,"53965":30493,"53966":30491,"53967":30480,"53968":30483,"53969":30482,"53970":30499,"53971":30481,"53972":30485,"53973":30489,"53974":30490,"53975":30498,"53976":30503,"53977":30755,"53978":30764,"53979":30754,"53980":30773,"53981":30767,"53982":30760,"53983":30766,"53984":30763,"53985":30753,"53986":30761,"53987":30771,"53988":30762,"53989":30769,"53990":31060,"53991":31067,"53992":31055,"53993":31068,"53994":31059,"53995":31058,"53996":31057,"53997":31211,"53998":31212,"53999":31200,"54000":31214,"54001":31213,"54002":31210,"54003":31196,"54004":31198,"54005":31197,"54006":31366,"54007":31369,"54008":31365,"54009":31371,"54010":31372,"54011":31370,"54012":31367,"54013":31448,"54014":31504,"54080":31492,"54081":31507,"54082":31493,"54083":31503,"54084":31496,"54085":31498,"54086":31502,"54087":31497,"54088":31506,"54089":31876,"54090":31889,"54091":31882,"54092":31884,"54093":31880,"54094":31885,"54095":31877,"54096":32030,"54097":32029,"54098":32017,"54099":32014,"54100":32024,"54101":32022,"54102":32019,"54103":32031,"54104":32018,"54105":32015,"54106":32012,"54107":32604,"54108":32609,"54109":32606,"54110":32608,"54111":32605,"54112":32603,"54113":32662,"54114":32658,"54115":32707,"54116":32706,"54117":32704,"54118":32790,"54119":32830,"54120":32825,"54121":33018,"54122":33010,"54123":33017,"54124":33013,"54125":33025,"54126":33019,"54127":33024,"54128":33281,"54129":33327,"54130":33317,"54131":33587,"54132":33581,"54133":33604,"54134":33561,"54135":33617,"54136":33573,"54137":33622,"54138":33599,"54139":33601,"54140":33574,"54141":33564,"54142":33570,"54177":33602,"54178":33614,"54179":33563,"54180":33578,"54181":33544,"54182":33596,"54183":33613,"54184":33558,"54185":33572,"54186":33568,"54187":33591,"54188":33583,"54189":33577,"54190":33607,"54191":33605,"54192":33612,"54193":33619,"54194":33566,"54195":33580,"54196":33611,"54197":33575,"54198":33608,"54199":34387,"54200":34386,"54201":34466,"54202":34472,"54203":34454,"54204":34445,"54205":34449,"54206":34462,"54207":34439,"54208":34455,"54209":34438,"54210":34443,"54211":34458,"54212":34437,"54213":34469,"54214":34457,"54215":34465,"54216":34471,"54217":34453,"54218":34456,"54219":34446,"54220":34461,"54221":34448,"54222":34452,"54223":34883,"54224":34884,"54225":34925,"54226":34933,"54227":34934,"54228":34930,"54229":34944,"54230":34929,"54231":34943,"54232":34927,"54233":34947,"54234":34942,"54235":34932,"54236":34940,"54237":35346,"54238":35911,"54239":35927,"54240":35963,"54241":36004,"54242":36003,"54243":36214,"54244":36216,"54245":36277,"54246":36279,"54247":36278,"54248":36561,"54249":36563,"54250":36862,"54251":36853,"54252":36866,"54253":36863,"54254":36859,"54255":36868,"54256":36860,"54257":36854,"54258":37078,"54259":37088,"54260":37081,"54261":37082,"54262":37091,"54263":37087,"54264":37093,"54265":37080,"54266":37083,"54267":37079,"54268":37084,"54269":37092,"54270":37200,"54336":37198,"54337":37199,"54338":37333,"54339":37346,"54340":37338,"54341":38492,"54342":38495,"54343":38588,"54344":39139,"54345":39647,"54346":39727,"54347":20095,"54348":20592,"54349":20586,"54350":20577,"54351":20574,"54352":20576,"54353":20563,"54354":20555,"54355":20573,"54356":20594,"54357":20552,"54358":20557,"54359":20545,"54360":20571,"54361":20554,"54362":20578,"54363":20501,"54364":20549,"54365":20575,"54366":20585,"54367":20587,"54368":20579,"54369":20580,"54370":20550,"54371":20544,"54372":20590,"54373":20595,"54374":20567,"54375":20561,"54376":20944,"54377":21099,"54378":21101,"54379":21100,"54380":21102,"54381":21206,"54382":21203,"54383":21293,"54384":21404,"54385":21877,"54386":21878,"54387":21820,"54388":21837,"54389":21840,"54390":21812,"54391":21802,"54392":21841,"54393":21858,"54394":21814,"54395":21813,"54396":21808,"54397":21842,"54398":21829,"54433":21772,"54434":21810,"54435":21861,"54436":21838,"54437":21817,"54438":21832,"54439":21805,"54440":21819,"54441":21824,"54442":21835,"54443":22282,"54444":22279,"54445":22523,"54446":22548,"54447":22498,"54448":22518,"54449":22492,"54450":22516,"54451":22528,"54452":22509,"54453":22525,"54454":22536,"54455":22520,"54456":22539,"54457":22515,"54458":22479,"54459":22535,"54460":22510,"54461":22499,"54462":22514,"54463":22501,"54464":22508,"54465":22497,"54466":22542,"54467":22524,"54468":22544,"54469":22503,"54470":22529,"54471":22540,"54472":22513,"54473":22505,"54474":22512,"54475":22541,"54476":22532,"54477":22876,"54478":23136,"54479":23128,"54480":23125,"54481":23143,"54482":23134,"54483":23096,"54484":23093,"54485":23149,"54486":23120,"54487":23135,"54488":23141,"54489":23148,"54490":23123,"54491":23140,"54492":23127,"54493":23107,"54494":23133,"54495":23122,"54496":23108,"54497":23131,"54498":23112,"54499":23182,"54500":23102,"54501":23117,"54502":23097,"54503":23116,"54504":23152,"54505":23145,"54506":23111,"54507":23121,"54508":23126,"54509":23106,"54510":23132,"54511":23410,"54512":23406,"54513":23489,"54514":23488,"54515":23641,"54516":23838,"54517":23819,"54518":23837,"54519":23834,"54520":23840,"54521":23820,"54522":23848,"54523":23821,"54524":23846,"54525":23845,"54526":23823,"54592":23856,"54593":23826,"54594":23843,"54595":23839,"54596":23854,"54597":24126,"54598":24116,"54599":24241,"54600":24244,"54601":24249,"54602":24242,"54603":24243,"54604":24374,"54605":24376,"54606":24475,"54607":24470,"54608":24479,"54609":24714,"54610":24720,"54611":24710,"54612":24766,"54613":24752,"54614":24762,"54615":24787,"54616":24788,"54617":24783,"54618":24804,"54619":24793,"54620":24797,"54621":24776,"54622":24753,"54623":24795,"54624":24759,"54625":24778,"54626":24767,"54627":24771,"54628":24781,"54629":24768,"54630":25394,"54631":25445,"54632":25482,"54633":25474,"54634":25469,"54635":25533,"54636":25502,"54637":25517,"54638":25501,"54639":25495,"54640":25515,"54641":25486,"54642":25455,"54643":25479,"54644":25488,"54645":25454,"54646":25519,"54647":25461,"54648":25500,"54649":25453,"54650":25518,"54651":25468,"54652":25508,"54653":25403,"54654":25503,"54689":25464,"54690":25477,"54691":25473,"54692":25489,"54693":25485,"54694":25456,"54695":25939,"54696":26061,"54697":26213,"54698":26209,"54699":26203,"54700":26201,"54701":26204,"54702":26210,"54703":26392,"54704":26745,"54705":26759,"54706":26768,"54707":26780,"54708":26733,"54709":26734,"54710":26798,"54711":26795,"54712":26966,"54713":26735,"54714":26787,"54715":26796,"54716":26793,"54717":26741,"54718":26740,"54719":26802,"54720":26767,"54721":26743,"54722":26770,"54723":26748,"54724":26731,"54725":26738,"54726":26794,"54727":26752,"54728":26737,"54729":26750,"54730":26779,"54731":26774,"54732":26763,"54733":26784,"54734":26761,"54735":26788,"54736":26744,"54737":26747,"54738":26769,"54739":26764,"54740":26762,"54741":26749,"54742":27446,"54743":27443,"54744":27447,"54745":27448,"54746":27537,"54747":27535,"54748":27533,"54749":27534,"54750":27532,"54751":27690,"54752":28096,"54753":28075,"54754":28084,"54755":28083,"54756":28276,"54757":28076,"54758":28137,"54759":28130,"54760":28087,"54761":28150,"54762":28116,"54763":28160,"54764":28104,"54765":28128,"54766":28127,"54767":28118,"54768":28094,"54769":28133,"54770":28124,"54771":28125,"54772":28123,"54773":28148,"54774":28106,"54775":28093,"54776":28141,"54777":28144,"54778":28090,"54779":28117,"54780":28098,"54781":28111,"54782":28105,"54848":28112,"54849":28146,"54850":28115,"54851":28157,"54852":28119,"54853":28109,"54854":28131,"54855":28091,"54856":28922,"54857":28941,"54858":28919,"54859":28951,"54860":28916,"54861":28940,"54862":28912,"54863":28932,"54864":28915,"54865":28944,"54866":28924,"54867":28927,"54868":28934,"54869":28947,"54870":28928,"54871":28920,"54872":28918,"54873":28939,"54874":28930,"54875":28942,"54876":29310,"54877":29307,"54878":29308,"54879":29311,"54880":29469,"54881":29463,"54882":29447,"54883":29457,"54884":29464,"54885":29450,"54886":29448,"54887":29439,"54888":29455,"54889":29470,"54890":29576,"54891":29686,"54892":29688,"54893":29685,"54894":29700,"54895":29697,"54896":29693,"54897":29703,"54898":29696,"54899":29690,"54900":29692,"54901":29695,"54902":29708,"54903":29707,"54904":29684,"54905":29704,"54906":30052,"54907":30051,"54908":30158,"54909":30162,"54910":30159,"54945":30155,"54946":30156,"54947":30161,"54948":30160,"54949":30351,"54950":30345,"54951":30419,"54952":30521,"54953":30511,"54954":30509,"54955":30513,"54956":30514,"54957":30516,"54958":30515,"54959":30525,"54960":30501,"54961":30523,"54962":30517,"54963":30792,"54964":30802,"54965":30793,"54966":30797,"54967":30794,"54968":30796,"54969":30758,"54970":30789,"54971":30800,"54972":31076,"54973":31079,"54974":31081,"54975":31082,"54976":31075,"54977":31083,"54978":31073,"54979":31163,"54980":31226,"54981":31224,"54982":31222,"54983":31223,"54984":31375,"54985":31380,"54986":31376,"54987":31541,"54988":31559,"54989":31540,"54990":31525,"54991":31536,"54992":31522,"54993":31524,"54994":31539,"54995":31512,"54996":31530,"54997":31517,"54998":31537,"54999":31531,"55000":31533,"55001":31535,"55002":31538,"55003":31544,"55004":31514,"55005":31523,"55006":31892,"55007":31896,"55008":31894,"55009":31907,"55010":32053,"55011":32061,"55012":32056,"55013":32054,"55014":32058,"55015":32069,"55016":32044,"55017":32041,"55018":32065,"55019":32071,"55020":32062,"55021":32063,"55022":32074,"55023":32059,"55024":32040,"55025":32611,"55026":32661,"55027":32668,"55028":32669,"55029":32667,"55030":32714,"55031":32715,"55032":32717,"55033":32720,"55034":32721,"55035":32711,"55036":32719,"55037":32713,"55038":32799,"55104":32798,"55105":32795,"55106":32839,"55107":32835,"55108":32840,"55109":33048,"55110":33061,"55111":33049,"55112":33051,"55113":33069,"55114":33055,"55115":33068,"55116":33054,"55117":33057,"55118":33045,"55119":33063,"55120":33053,"55121":33058,"55122":33297,"55123":33336,"55124":33331,"55125":33338,"55126":33332,"55127":33330,"55128":33396,"55129":33680,"55130":33699,"55131":33704,"55132":33677,"55133":33658,"55134":33651,"55135":33700,"55136":33652,"55137":33679,"55138":33665,"55139":33685,"55140":33689,"55141":33653,"55142":33684,"55143":33705,"55144":33661,"55145":33667,"55146":33676,"55147":33693,"55148":33691,"55149":33706,"55150":33675,"55151":33662,"55152":33701,"55153":33711,"55154":33672,"55155":33687,"55156":33712,"55157":33663,"55158":33702,"55159":33671,"55160":33710,"55161":33654,"55162":33690,"55163":34393,"55164":34390,"55165":34495,"55166":34487,"55201":34498,"55202":34497,"55203":34501,"55204":34490,"55205":34480,"55206":34504,"55207":34489,"55208":34483,"55209":34488,"55210":34508,"55211":34484,"55212":34491,"55213":34492,"55214":34499,"55215":34493,"55216":34494,"55217":34898,"55218":34953,"55219":34965,"55220":34984,"55221":34978,"55222":34986,"55223":34970,"55224":34961,"55225":34977,"55226":34975,"55227":34968,"55228":34983,"55229":34969,"55230":34971,"55231":34967,"55232":34980,"55233":34988,"55234":34956,"55235":34963,"55236":34958,"55237":35202,"55238":35286,"55239":35289,"55240":35285,"55241":35376,"55242":35367,"55243":35372,"55244":35358,"55245":35897,"55246":35899,"55247":35932,"55248":35933,"55249":35965,"55250":36005,"55251":36221,"55252":36219,"55253":36217,"55254":36284,"55255":36290,"55256":36281,"55257":36287,"55258":36289,"55259":36568,"55260":36574,"55261":36573,"55262":36572,"55263":36567,"55264":36576,"55265":36577,"55266":36900,"55267":36875,"55268":36881,"55269":36892,"55270":36876,"55271":36897,"55272":37103,"55273":37098,"55274":37104,"55275":37108,"55276":37106,"55277":37107,"55278":37076,"55279":37099,"55280":37100,"55281":37097,"55282":37206,"55283":37208,"55284":37210,"55285":37203,"55286":37205,"55287":37356,"55288":37364,"55289":37361,"55290":37363,"55291":37368,"55292":37348,"55293":37369,"55294":37354,"55360":37355,"55361":37367,"55362":37352,"55363":37358,"55364":38266,"55365":38278,"55366":38280,"55367":38524,"55368":38509,"55369":38507,"55370":38513,"55371":38511,"55372":38591,"55373":38762,"55374":38916,"55375":39141,"55376":39319,"55377":20635,"55378":20629,"55379":20628,"55380":20638,"55381":20619,"55382":20643,"55383":20611,"55384":20620,"55385":20622,"55386":20637,"55387":20584,"55388":20636,"55389":20626,"55390":20610,"55391":20615,"55392":20831,"55393":20948,"55394":21266,"55395":21265,"55396":21412,"55397":21415,"55398":21905,"55399":21928,"55400":21925,"55401":21933,"55402":21879,"55403":22085,"55404":21922,"55405":21907,"55406":21896,"55407":21903,"55408":21941,"55409":21889,"55410":21923,"55411":21906,"55412":21924,"55413":21885,"55414":21900,"55415":21926,"55416":21887,"55417":21909,"55418":21921,"55419":21902,"55420":22284,"55421":22569,"55422":22583,"55457":22553,"55458":22558,"55459":22567,"55460":22563,"55461":22568,"55462":22517,"55463":22600,"55464":22565,"55465":22556,"55466":22555,"55467":22579,"55468":22591,"55469":22582,"55470":22574,"55471":22585,"55472":22584,"55473":22573,"55474":22572,"55475":22587,"55476":22881,"55477":23215,"55478":23188,"55479":23199,"55480":23162,"55481":23202,"55482":23198,"55483":23160,"55484":23206,"55485":23164,"55486":23205,"55487":23212,"55488":23189,"55489":23214,"55490":23095,"55491":23172,"55492":23178,"55493":23191,"55494":23171,"55495":23179,"55496":23209,"55497":23163,"55498":23165,"55499":23180,"55500":23196,"55501":23183,"55502":23187,"55503":23197,"55504":23530,"55505":23501,"55506":23499,"55507":23508,"55508":23505,"55509":23498,"55510":23502,"55511":23564,"55512":23600,"55513":23863,"55514":23875,"55515":23915,"55516":23873,"55517":23883,"55518":23871,"55519":23861,"55520":23889,"55521":23886,"55522":23893,"55523":23859,"55524":23866,"55525":23890,"55526":23869,"55527":23857,"55528":23897,"55529":23874,"55530":23865,"55531":23881,"55532":23864,"55533":23868,"55534":23858,"55535":23862,"55536":23872,"55537":23877,"55538":24132,"55539":24129,"55540":24408,"55541":24486,"55542":24485,"55543":24491,"55544":24777,"55545":24761,"55546":24780,"55547":24802,"55548":24782,"55549":24772,"55550":24852,"55616":24818,"55617":24842,"55618":24854,"55619":24837,"55620":24821,"55621":24851,"55622":24824,"55623":24828,"55624":24830,"55625":24769,"55626":24835,"55627":24856,"55628":24861,"55629":24848,"55630":24831,"55631":24836,"55632":24843,"55633":25162,"55634":25492,"55635":25521,"55636":25520,"55637":25550,"55638":25573,"55639":25576,"55640":25583,"55641":25539,"55642":25757,"55643":25587,"55644":25546,"55645":25568,"55646":25590,"55647":25557,"55648":25586,"55649":25589,"55650":25697,"55651":25567,"55652":25534,"55653":25565,"55654":25564,"55655":25540,"55656":25560,"55657":25555,"55658":25538,"55659":25543,"55660":25548,"55661":25547,"55662":25544,"55663":25584,"55664":25559,"55665":25561,"55666":25906,"55667":25959,"55668":25962,"55669":25956,"55670":25948,"55671":25960,"55672":25957,"55673":25996,"55674":26013,"55675":26014,"55676":26030,"55677":26064,"55678":26066,"55713":26236,"55714":26220,"55715":26235,"55716":26240,"55717":26225,"55718":26233,"55719":26218,"55720":26226,"55721":26369,"55722":26892,"55723":26835,"55724":26884,"55725":26844,"55726":26922,"55727":26860,"55728":26858,"55729":26865,"55730":26895,"55731":26838,"55732":26871,"55733":26859,"55734":26852,"55735":26870,"55736":26899,"55737":26896,"55738":26867,"55739":26849,"55740":26887,"55741":26828,"55742":26888,"55743":26992,"55744":26804,"55745":26897,"55746":26863,"55747":26822,"55748":26900,"55749":26872,"55750":26832,"55751":26877,"55752":26876,"55753":26856,"55754":26891,"55755":26890,"55756":26903,"55757":26830,"55758":26824,"55759":26845,"55760":26846,"55761":26854,"55762":26868,"55763":26833,"55764":26886,"55765":26836,"55766":26857,"55767":26901,"55768":26917,"55769":26823,"55770":27449,"55771":27451,"55772":27455,"55773":27452,"55774":27540,"55775":27543,"55776":27545,"55777":27541,"55778":27581,"55779":27632,"55780":27634,"55781":27635,"55782":27696,"55783":28156,"55784":28230,"55785":28231,"55786":28191,"55787":28233,"55788":28296,"55789":28220,"55790":28221,"55791":28229,"55792":28258,"55793":28203,"55794":28223,"55795":28225,"55796":28253,"55797":28275,"55798":28188,"55799":28211,"55800":28235,"55801":28224,"55802":28241,"55803":28219,"55804":28163,"55805":28206,"55806":28254,"55872":28264,"55873":28252,"55874":28257,"55875":28209,"55876":28200,"55877":28256,"55878":28273,"55879":28267,"55880":28217,"55881":28194,"55882":28208,"55883":28243,"55884":28261,"55885":28199,"55886":28280,"55887":28260,"55888":28279,"55889":28245,"55890":28281,"55891":28242,"55892":28262,"55893":28213,"55894":28214,"55895":28250,"55896":28960,"55897":28958,"55898":28975,"55899":28923,"55900":28974,"55901":28977,"55902":28963,"55903":28965,"55904":28962,"55905":28978,"55906":28959,"55907":28968,"55908":28986,"55909":28955,"55910":29259,"55911":29274,"55912":29320,"55913":29321,"55914":29318,"55915":29317,"55916":29323,"55917":29458,"55918":29451,"55919":29488,"55920":29474,"55921":29489,"55922":29491,"55923":29479,"55924":29490,"55925":29485,"55926":29478,"55927":29475,"55928":29493,"55929":29452,"55930":29742,"55931":29740,"55932":29744,"55933":29739,"55934":29718,"55969":29722,"55970":29729,"55971":29741,"55972":29745,"55973":29732,"55974":29731,"55975":29725,"55976":29737,"55977":29728,"55978":29746,"55979":29947,"55980":29999,"55981":30063,"55982":30060,"55983":30183,"55984":30170,"55985":30177,"55986":30182,"55987":30173,"55988":30175,"55989":30180,"55990":30167,"55991":30357,"55992":30354,"55993":30426,"55994":30534,"55995":30535,"55996":30532,"55997":30541,"55998":30533,"55999":30538,"56000":30542,"56001":30539,"56002":30540,"56003":30686,"56004":30700,"56005":30816,"56006":30820,"56007":30821,"56008":30812,"56009":30829,"56010":30833,"56011":30826,"56012":30830,"56013":30832,"56014":30825,"56015":30824,"56016":30814,"56017":30818,"56018":31092,"56019":31091,"56020":31090,"56021":31088,"56022":31234,"56023":31242,"56024":31235,"56025":31244,"56026":31236,"56027":31385,"56028":31462,"56029":31460,"56030":31562,"56031":31547,"56032":31556,"56033":31560,"56034":31564,"56035":31566,"56036":31552,"56037":31576,"56038":31557,"56039":31906,"56040":31902,"56041":31912,"56042":31905,"56043":32088,"56044":32111,"56045":32099,"56046":32083,"56047":32086,"56048":32103,"56049":32106,"56050":32079,"56051":32109,"56052":32092,"56053":32107,"56054":32082,"56055":32084,"56056":32105,"56057":32081,"56058":32095,"56059":32078,"56060":32574,"56061":32575,"56062":32613,"56128":32614,"56129":32674,"56130":32672,"56131":32673,"56132":32727,"56133":32849,"56134":32847,"56135":32848,"56136":33022,"56137":32980,"56138":33091,"56139":33098,"56140":33106,"56141":33103,"56142":33095,"56143":33085,"56144":33101,"56145":33082,"56146":33254,"56147":33262,"56148":33271,"56149":33272,"56150":33273,"56151":33284,"56152":33340,"56153":33341,"56154":33343,"56155":33397,"56156":33595,"56157":33743,"56158":33785,"56159":33827,"56160":33728,"56161":33768,"56162":33810,"56163":33767,"56164":33764,"56165":33788,"56166":33782,"56167":33808,"56168":33734,"56169":33736,"56170":33771,"56171":33763,"56172":33727,"56173":33793,"56174":33757,"56175":33765,"56176":33752,"56177":33791,"56178":33761,"56179":33739,"56180":33742,"56181":33750,"56182":33781,"56183":33737,"56184":33801,"56185":33807,"56186":33758,"56187":33809,"56188":33798,"56189":33730,"56190":33779,"56225":33749,"56226":33786,"56227":33735,"56228":33745,"56229":33770,"56230":33811,"56231":33731,"56232":33772,"56233":33774,"56234":33732,"56235":33787,"56236":33751,"56237":33762,"56238":33819,"56239":33755,"56240":33790,"56241":34520,"56242":34530,"56243":34534,"56244":34515,"56245":34531,"56246":34522,"56247":34538,"56248":34525,"56249":34539,"56250":34524,"56251":34540,"56252":34537,"56253":34519,"56254":34536,"56255":34513,"56256":34888,"56257":34902,"56258":34901,"56259":35002,"56260":35031,"56261":35001,"56262":35000,"56263":35008,"56264":35006,"56265":34998,"56266":35004,"56267":34999,"56268":35005,"56269":34994,"56270":35073,"56271":35017,"56272":35221,"56273":35224,"56274":35223,"56275":35293,"56276":35290,"56277":35291,"56278":35406,"56279":35405,"56280":35385,"56281":35417,"56282":35392,"56283":35415,"56284":35416,"56285":35396,"56286":35397,"56287":35410,"56288":35400,"56289":35409,"56290":35402,"56291":35404,"56292":35407,"56293":35935,"56294":35969,"56295":35968,"56296":36026,"56297":36030,"56298":36016,"56299":36025,"56300":36021,"56301":36228,"56302":36224,"56303":36233,"56304":36312,"56305":36307,"56306":36301,"56307":36295,"56308":36310,"56309":36316,"56310":36303,"56311":36309,"56312":36313,"56313":36296,"56314":36311,"56315":36293,"56316":36591,"56317":36599,"56318":36602,"56384":36601,"56385":36582,"56386":36590,"56387":36581,"56388":36597,"56389":36583,"56390":36584,"56391":36598,"56392":36587,"56393":36593,"56394":36588,"56395":36596,"56396":36585,"56397":36909,"56398":36916,"56399":36911,"56400":37126,"56401":37164,"56402":37124,"56403":37119,"56404":37116,"56405":37128,"56406":37113,"56407":37115,"56408":37121,"56409":37120,"56410":37127,"56411":37125,"56412":37123,"56413":37217,"56414":37220,"56415":37215,"56416":37218,"56417":37216,"56418":37377,"56419":37386,"56420":37413,"56421":37379,"56422":37402,"56423":37414,"56424":37391,"56425":37388,"56426":37376,"56427":37394,"56428":37375,"56429":37373,"56430":37382,"56431":37380,"56432":37415,"56433":37378,"56434":37404,"56435":37412,"56436":37401,"56437":37399,"56438":37381,"56439":37398,"56440":38267,"56441":38285,"56442":38284,"56443":38288,"56444":38535,"56445":38526,"56446":38536,"56481":38537,"56482":38531,"56483":38528,"56484":38594,"56485":38600,"56486":38595,"56487":38641,"56488":38640,"56489":38764,"56490":38768,"56491":38766,"56492":38919,"56493":39081,"56494":39147,"56495":40166,"56496":40697,"56497":20099,"56498":20100,"56499":20150,"56500":20669,"56501":20671,"56502":20678,"56503":20654,"56504":20676,"56505":20682,"56506":20660,"56507":20680,"56508":20674,"56509":20656,"56510":20673,"56511":20666,"56512":20657,"56513":20683,"56514":20681,"56515":20662,"56516":20664,"56517":20951,"56518":21114,"56519":21112,"56520":21115,"56521":21116,"56522":21955,"56523":21979,"56524":21964,"56525":21968,"56526":21963,"56527":21962,"56528":21981,"56529":21952,"56530":21972,"56531":21956,"56532":21993,"56533":21951,"56534":21970,"56535":21901,"56536":21967,"56537":21973,"56538":21986,"56539":21974,"56540":21960,"56541":22002,"56542":21965,"56543":21977,"56544":21954,"56545":22292,"56546":22611,"56547":22632,"56548":22628,"56549":22607,"56550":22605,"56551":22601,"56552":22639,"56553":22613,"56554":22606,"56555":22621,"56556":22617,"56557":22629,"56558":22619,"56559":22589,"56560":22627,"56561":22641,"56562":22780,"56563":23239,"56564":23236,"56565":23243,"56566":23226,"56567":23224,"56568":23217,"56569":23221,"56570":23216,"56571":23231,"56572":23240,"56573":23227,"56574":23238,"56640":23223,"56641":23232,"56642":23242,"56643":23220,"56644":23222,"56645":23245,"56646":23225,"56647":23184,"56648":23510,"56649":23512,"56650":23513,"56651":23583,"56652":23603,"56653":23921,"56654":23907,"56655":23882,"56656":23909,"56657":23922,"56658":23916,"56659":23902,"56660":23912,"56661":23911,"56662":23906,"56663":24048,"56664":24143,"56665":24142,"56666":24138,"56667":24141,"56668":24139,"56669":24261,"56670":24268,"56671":24262,"56672":24267,"56673":24263,"56674":24384,"56675":24495,"56676":24493,"56677":24823,"56678":24905,"56679":24906,"56680":24875,"56681":24901,"56682":24886,"56683":24882,"56684":24878,"56685":24902,"56686":24879,"56687":24911,"56688":24873,"56689":24896,"56690":25120,"56691":37224,"56692":25123,"56693":25125,"56694":25124,"56695":25541,"56696":25585,"56697":25579,"56698":25616,"56699":25618,"56700":25609,"56701":25632,"56702":25636,"56737":25651,"56738":25667,"56739":25631,"56740":25621,"56741":25624,"56742":25657,"56743":25655,"56744":25634,"56745":25635,"56746":25612,"56747":25638,"56748":25648,"56749":25640,"56750":25665,"56751":25653,"56752":25647,"56753":25610,"56754":25626,"56755":25664,"56756":25637,"56757":25639,"56758":25611,"56759":25575,"56760":25627,"56761":25646,"56762":25633,"56763":25614,"56764":25967,"56765":26002,"56766":26067,"56767":26246,"56768":26252,"56769":26261,"56770":26256,"56771":26251,"56772":26250,"56773":26265,"56774":26260,"56775":26232,"56776":26400,"56777":26982,"56778":26975,"56779":26936,"56780":26958,"56781":26978,"56782":26993,"56783":26943,"56784":26949,"56785":26986,"56786":26937,"56787":26946,"56788":26967,"56789":26969,"56790":27002,"56791":26952,"56792":26953,"56793":26933,"56794":26988,"56795":26931,"56796":26941,"56797":26981,"56798":26864,"56799":27000,"56800":26932,"56801":26985,"56802":26944,"56803":26991,"56804":26948,"56805":26998,"56806":26968,"56807":26945,"56808":26996,"56809":26956,"56810":26939,"56811":26955,"56812":26935,"56813":26972,"56814":26959,"56815":26961,"56816":26930,"56817":26962,"56818":26927,"56819":27003,"56820":26940,"56821":27462,"56822":27461,"56823":27459,"56824":27458,"56825":27464,"56826":27457,"56827":27547,"56828":64013,"56829":27643,"56830":27644,"56896":27641,"56897":27639,"56898":27640,"56899":28315,"56900":28374,"56901":28360,"56902":28303,"56903":28352,"56904":28319,"56905":28307,"56906":28308,"56907":28320,"56908":28337,"56909":28345,"56910":28358,"56911":28370,"56912":28349,"56913":28353,"56914":28318,"56915":28361,"56916":28343,"56917":28336,"56918":28365,"56919":28326,"56920":28367,"56921":28338,"56922":28350,"56923":28355,"56924":28380,"56925":28376,"56926":28313,"56927":28306,"56928":28302,"56929":28301,"56930":28324,"56931":28321,"56932":28351,"56933":28339,"56934":28368,"56935":28362,"56936":28311,"56937":28334,"56938":28323,"56939":28999,"56940":29012,"56941":29010,"56942":29027,"56943":29024,"56944":28993,"56945":29021,"56946":29026,"56947":29042,"56948":29048,"56949":29034,"56950":29025,"56951":28994,"56952":29016,"56953":28995,"56954":29003,"56955":29040,"56956":29023,"56957":29008,"56958":29011,"56993":28996,"56994":29005,"56995":29018,"56996":29263,"56997":29325,"56998":29324,"56999":29329,"57000":29328,"57001":29326,"57002":29500,"57003":29506,"57004":29499,"57005":29498,"57006":29504,"57007":29514,"57008":29513,"57009":29764,"57010":29770,"57011":29771,"57012":29778,"57013":29777,"57014":29783,"57015":29760,"57016":29775,"57017":29776,"57018":29774,"57019":29762,"57020":29766,"57021":29773,"57022":29780,"57023":29921,"57024":29951,"57025":29950,"57026":29949,"57027":29981,"57028":30073,"57029":30071,"57030":27011,"57031":30191,"57032":30223,"57033":30211,"57034":30199,"57035":30206,"57036":30204,"57037":30201,"57038":30200,"57039":30224,"57040":30203,"57041":30198,"57042":30189,"57043":30197,"57044":30205,"57045":30361,"57046":30389,"57047":30429,"57048":30549,"57049":30559,"57050":30560,"57051":30546,"57052":30550,"57053":30554,"57054":30569,"57055":30567,"57056":30548,"57057":30553,"57058":30573,"57059":30688,"57060":30855,"57061":30874,"57062":30868,"57063":30863,"57064":30852,"57065":30869,"57066":30853,"57067":30854,"57068":30881,"57069":30851,"57070":30841,"57071":30873,"57072":30848,"57073":30870,"57074":30843,"57075":31100,"57076":31106,"57077":31101,"57078":31097,"57079":31249,"57080":31256,"57081":31257,"57082":31250,"57083":31255,"57084":31253,"57085":31266,"57086":31251,"57152":31259,"57153":31248,"57154":31395,"57155":31394,"57156":31390,"57157":31467,"57158":31590,"57159":31588,"57160":31597,"57161":31604,"57162":31593,"57163":31602,"57164":31589,"57165":31603,"57166":31601,"57167":31600,"57168":31585,"57169":31608,"57170":31606,"57171":31587,"57172":31922,"57173":31924,"57174":31919,"57175":32136,"57176":32134,"57177":32128,"57178":32141,"57179":32127,"57180":32133,"57181":32122,"57182":32142,"57183":32123,"57184":32131,"57185":32124,"57186":32140,"57187":32148,"57188":32132,"57189":32125,"57190":32146,"57191":32621,"57192":32619,"57193":32615,"57194":32616,"57195":32620,"57196":32678,"57197":32677,"57198":32679,"57199":32731,"57200":32732,"57201":32801,"57202":33124,"57203":33120,"57204":33143,"57205":33116,"57206":33129,"57207":33115,"57208":33122,"57209":33138,"57210":26401,"57211":33118,"57212":33142,"57213":33127,"57214":33135,"57249":33092,"57250":33121,"57251":33309,"57252":33353,"57253":33348,"57254":33344,"57255":33346,"57256":33349,"57257":34033,"57258":33855,"57259":33878,"57260":33910,"57261":33913,"57262":33935,"57263":33933,"57264":33893,"57265":33873,"57266":33856,"57267":33926,"57268":33895,"57269":33840,"57270":33869,"57271":33917,"57272":33882,"57273":33881,"57274":33908,"57275":33907,"57276":33885,"57277":34055,"57278":33886,"57279":33847,"57280":33850,"57281":33844,"57282":33914,"57283":33859,"57284":33912,"57285":33842,"57286":33861,"57287":33833,"57288":33753,"57289":33867,"57290":33839,"57291":33858,"57292":33837,"57293":33887,"57294":33904,"57295":33849,"57296":33870,"57297":33868,"57298":33874,"57299":33903,"57300":33989,"57301":33934,"57302":33851,"57303":33863,"57304":33846,"57305":33843,"57306":33896,"57307":33918,"57308":33860,"57309":33835,"57310":33888,"57311":33876,"57312":33902,"57313":33872,"57314":34571,"57315":34564,"57316":34551,"57317":34572,"57318":34554,"57319":34518,"57320":34549,"57321":34637,"57322":34552,"57323":34574,"57324":34569,"57325":34561,"57326":34550,"57327":34573,"57328":34565,"57329":35030,"57330":35019,"57331":35021,"57332":35022,"57333":35038,"57334":35035,"57335":35034,"57336":35020,"57337":35024,"57338":35205,"57339":35227,"57340":35295,"57341":35301,"57342":35300,"57408":35297,"57409":35296,"57410":35298,"57411":35292,"57412":35302,"57413":35446,"57414":35462,"57415":35455,"57416":35425,"57417":35391,"57418":35447,"57419":35458,"57420":35460,"57421":35445,"57422":35459,"57423":35457,"57424":35444,"57425":35450,"57426":35900,"57427":35915,"57428":35914,"57429":35941,"57430":35940,"57431":35942,"57432":35974,"57433":35972,"57434":35973,"57435":36044,"57436":36200,"57437":36201,"57438":36241,"57439":36236,"57440":36238,"57441":36239,"57442":36237,"57443":36243,"57444":36244,"57445":36240,"57446":36242,"57447":36336,"57448":36320,"57449":36332,"57450":36337,"57451":36334,"57452":36304,"57453":36329,"57454":36323,"57455":36322,"57456":36327,"57457":36338,"57458":36331,"57459":36340,"57460":36614,"57461":36607,"57462":36609,"57463":36608,"57464":36613,"57465":36615,"57466":36616,"57467":36610,"57468":36619,"57469":36946,"57470":36927,"57505":36932,"57506":36937,"57507":36925,"57508":37136,"57509":37133,"57510":37135,"57511":37137,"57512":37142,"57513":37140,"57514":37131,"57515":37134,"57516":37230,"57517":37231,"57518":37448,"57519":37458,"57520":37424,"57521":37434,"57522":37478,"57523":37427,"57524":37477,"57525":37470,"57526":37507,"57527":37422,"57528":37450,"57529":37446,"57530":37485,"57531":37484,"57532":37455,"57533":37472,"57534":37479,"57535":37487,"57536":37430,"57537":37473,"57538":37488,"57539":37425,"57540":37460,"57541":37475,"57542":37456,"57543":37490,"57544":37454,"57545":37459,"57546":37452,"57547":37462,"57548":37426,"57549":38303,"57550":38300,"57551":38302,"57552":38299,"57553":38546,"57554":38547,"57555":38545,"57556":38551,"57557":38606,"57558":38650,"57559":38653,"57560":38648,"57561":38645,"57562":38771,"57563":38775,"57564":38776,"57565":38770,"57566":38927,"57567":38925,"57568":38926,"57569":39084,"57570":39158,"57571":39161,"57572":39343,"57573":39346,"57574":39344,"57575":39349,"57576":39597,"57577":39595,"57578":39771,"57579":40170,"57580":40173,"57581":40167,"57582":40576,"57583":40701,"57584":20710,"57585":20692,"57586":20695,"57587":20712,"57588":20723,"57589":20699,"57590":20714,"57591":20701,"57592":20708,"57593":20691,"57594":20716,"57595":20720,"57596":20719,"57597":20707,"57598":20704,"57664":20952,"57665":21120,"57666":21121,"57667":21225,"57668":21227,"57669":21296,"57670":21420,"57671":22055,"57672":22037,"57673":22028,"57674":22034,"57675":22012,"57676":22031,"57677":22044,"57678":22017,"57679":22035,"57680":22018,"57681":22010,"57682":22045,"57683":22020,"57684":22015,"57685":22009,"57686":22665,"57687":22652,"57688":22672,"57689":22680,"57690":22662,"57691":22657,"57692":22655,"57693":22644,"57694":22667,"57695":22650,"57696":22663,"57697":22673,"57698":22670,"57699":22646,"57700":22658,"57701":22664,"57702":22651,"57703":22676,"57704":22671,"57705":22782,"57706":22891,"57707":23260,"57708":23278,"57709":23269,"57710":23253,"57711":23274,"57712":23258,"57713":23277,"57714":23275,"57715":23283,"57716":23266,"57717":23264,"57718":23259,"57719":23276,"57720":23262,"57721":23261,"57722":23257,"57723":23272,"57724":23263,"57725":23415,"57726":23520,"57761":23523,"57762":23651,"57763":23938,"57764":23936,"57765":23933,"57766":23942,"57767":23930,"57768":23937,"57769":23927,"57770":23946,"57771":23945,"57772":23944,"57773":23934,"57774":23932,"57775":23949,"57776":23929,"57777":23935,"57778":24152,"57779":24153,"57780":24147,"57781":24280,"57782":24273,"57783":24279,"57784":24270,"57785":24284,"57786":24277,"57787":24281,"57788":24274,"57789":24276,"57790":24388,"57791":24387,"57792":24431,"57793":24502,"57794":24876,"57795":24872,"57796":24897,"57797":24926,"57798":24945,"57799":24947,"57800":24914,"57801":24915,"57802":24946,"57803":24940,"57804":24960,"57805":24948,"57806":24916,"57807":24954,"57808":24923,"57809":24933,"57810":24891,"57811":24938,"57812":24929,"57813":24918,"57814":25129,"57815":25127,"57816":25131,"57817":25643,"57818":25677,"57819":25691,"57820":25693,"57821":25716,"57822":25718,"57823":25714,"57824":25715,"57825":25725,"57826":25717,"57827":25702,"57828":25766,"57829":25678,"57830":25730,"57831":25694,"57832":25692,"57833":25675,"57834":25683,"57835":25696,"57836":25680,"57837":25727,"57838":25663,"57839":25708,"57840":25707,"57841":25689,"57842":25701,"57843":25719,"57844":25971,"57845":26016,"57846":26273,"57847":26272,"57848":26271,"57849":26373,"57850":26372,"57851":26402,"57852":27057,"57853":27062,"57854":27081,"57920":27040,"57921":27086,"57922":27030,"57923":27056,"57924":27052,"57925":27068,"57926":27025,"57927":27033,"57928":27022,"57929":27047,"57930":27021,"57931":27049,"57932":27070,"57933":27055,"57934":27071,"57935":27076,"57936":27069,"57937":27044,"57938":27092,"57939":27065,"57940":27082,"57941":27034,"57942":27087,"57943":27059,"57944":27027,"57945":27050,"57946":27041,"57947":27038,"57948":27097,"57949":27031,"57950":27024,"57951":27074,"57952":27061,"57953":27045,"57954":27078,"57955":27466,"57956":27469,"57957":27467,"57958":27550,"57959":27551,"57960":27552,"57961":27587,"57962":27588,"57963":27646,"57964":28366,"57965":28405,"57966":28401,"57967":28419,"57968":28453,"57969":28408,"57970":28471,"57971":28411,"57972":28462,"57973":28425,"57974":28494,"57975":28441,"57976":28442,"57977":28455,"57978":28440,"57979":28475,"57980":28434,"57981":28397,"57982":28426,"58017":28470,"58018":28531,"58019":28409,"58020":28398,"58021":28461,"58022":28480,"58023":28464,"58024":28476,"58025":28469,"58026":28395,"58027":28423,"58028":28430,"58029":28483,"58030":28421,"58031":28413,"58032":28406,"58033":28473,"58034":28444,"58035":28412,"58036":28474,"58037":28447,"58038":28429,"58039":28446,"58040":28424,"58041":28449,"58042":29063,"58043":29072,"58044":29065,"58045":29056,"58046":29061,"58047":29058,"58048":29071,"58049":29051,"58050":29062,"58051":29057,"58052":29079,"58053":29252,"58054":29267,"58055":29335,"58056":29333,"58057":29331,"58058":29507,"58059":29517,"58060":29521,"58061":29516,"58062":29794,"58063":29811,"58064":29809,"58065":29813,"58066":29810,"58067":29799,"58068":29806,"58069":29952,"58070":29954,"58071":29955,"58072":30077,"58073":30096,"58074":30230,"58075":30216,"58076":30220,"58077":30229,"58078":30225,"58079":30218,"58080":30228,"58081":30392,"58082":30593,"58083":30588,"58084":30597,"58085":30594,"58086":30574,"58087":30592,"58088":30575,"58089":30590,"58090":30595,"58091":30898,"58092":30890,"58093":30900,"58094":30893,"58095":30888,"58096":30846,"58097":30891,"58098":30878,"58099":30885,"58100":30880,"58101":30892,"58102":30882,"58103":30884,"58104":31128,"58105":31114,"58106":31115,"58107":31126,"58108":31125,"58109":31124,"58110":31123,"58176":31127,"58177":31112,"58178":31122,"58179":31120,"58180":31275,"58181":31306,"58182":31280,"58183":31279,"58184":31272,"58185":31270,"58186":31400,"58187":31403,"58188":31404,"58189":31470,"58190":31624,"58191":31644,"58192":31626,"58193":31633,"58194":31632,"58195":31638,"58196":31629,"58197":31628,"58198":31643,"58199":31630,"58200":31621,"58201":31640,"58202":21124,"58203":31641,"58204":31652,"58205":31618,"58206":31931,"58207":31935,"58208":31932,"58209":31930,"58210":32167,"58211":32183,"58212":32194,"58213":32163,"58214":32170,"58215":32193,"58216":32192,"58217":32197,"58218":32157,"58219":32206,"58220":32196,"58221":32198,"58222":32203,"58223":32204,"58224":32175,"58225":32185,"58226":32150,"58227":32188,"58228":32159,"58229":32166,"58230":32174,"58231":32169,"58232":32161,"58233":32201,"58234":32627,"58235":32738,"58236":32739,"58237":32741,"58238":32734,"58273":32804,"58274":32861,"58275":32860,"58276":33161,"58277":33158,"58278":33155,"58279":33159,"58280":33165,"58281":33164,"58282":33163,"58283":33301,"58284":33943,"58285":33956,"58286":33953,"58287":33951,"58288":33978,"58289":33998,"58290":33986,"58291":33964,"58292":33966,"58293":33963,"58294":33977,"58295":33972,"58296":33985,"58297":33997,"58298":33962,"58299":33946,"58300":33969,"58301":34000,"58302":33949,"58303":33959,"58304":33979,"58305":33954,"58306":33940,"58307":33991,"58308":33996,"58309":33947,"58310":33961,"58311":33967,"58312":33960,"58313":34006,"58314":33944,"58315":33974,"58316":33999,"58317":33952,"58318":34007,"58319":34004,"58320":34002,"58321":34011,"58322":33968,"58323":33937,"58324":34401,"58325":34611,"58326":34595,"58327":34600,"58328":34667,"58329":34624,"58330":34606,"58331":34590,"58332":34593,"58333":34585,"58334":34587,"58335":34627,"58336":34604,"58337":34625,"58338":34622,"58339":34630,"58340":34592,"58341":34610,"58342":34602,"58343":34605,"58344":34620,"58345":34578,"58346":34618,"58347":34609,"58348":34613,"58349":34626,"58350":34598,"58351":34599,"58352":34616,"58353":34596,"58354":34586,"58355":34608,"58356":34577,"58357":35063,"58358":35047,"58359":35057,"58360":35058,"58361":35066,"58362":35070,"58363":35054,"58364":35068,"58365":35062,"58366":35067,"58432":35056,"58433":35052,"58434":35051,"58435":35229,"58436":35233,"58437":35231,"58438":35230,"58439":35305,"58440":35307,"58441":35304,"58442":35499,"58443":35481,"58444":35467,"58445":35474,"58446":35471,"58447":35478,"58448":35901,"58449":35944,"58450":35945,"58451":36053,"58452":36047,"58453":36055,"58454":36246,"58455":36361,"58456":36354,"58457":36351,"58458":36365,"58459":36349,"58460":36362,"58461":36355,"58462":36359,"58463":36358,"58464":36357,"58465":36350,"58466":36352,"58467":36356,"58468":36624,"58469":36625,"58470":36622,"58471":36621,"58472":37155,"58473":37148,"58474":37152,"58475":37154,"58476":37151,"58477":37149,"58478":37146,"58479":37156,"58480":37153,"58481":37147,"58482":37242,"58483":37234,"58484":37241,"58485":37235,"58486":37541,"58487":37540,"58488":37494,"58489":37531,"58490":37498,"58491":37536,"58492":37524,"58493":37546,"58494":37517,"58529":37542,"58530":37530,"58531":37547,"58532":37497,"58533":37527,"58534":37503,"58535":37539,"58536":37614,"58537":37518,"58538":37506,"58539":37525,"58540":37538,"58541":37501,"58542":37512,"58543":37537,"58544":37514,"58545":37510,"58546":37516,"58547":37529,"58548":37543,"58549":37502,"58550":37511,"58551":37545,"58552":37533,"58553":37515,"58554":37421,"58555":38558,"58556":38561,"58557":38655,"58558":38744,"58559":38781,"58560":38778,"58561":38782,"58562":38787,"58563":38784,"58564":38786,"58565":38779,"58566":38788,"58567":38785,"58568":38783,"58569":38862,"58570":38861,"58571":38934,"58572":39085,"58573":39086,"58574":39170,"58575":39168,"58576":39175,"58577":39325,"58578":39324,"58579":39363,"58580":39353,"58581":39355,"58582":39354,"58583":39362,"58584":39357,"58585":39367,"58586":39601,"58587":39651,"58588":39655,"58589":39742,"58590":39743,"58591":39776,"58592":39777,"58593":39775,"58594":40177,"58595":40178,"58596":40181,"58597":40615,"58598":20735,"58599":20739,"58600":20784,"58601":20728,"58602":20742,"58603":20743,"58604":20726,"58605":20734,"58606":20747,"58607":20748,"58608":20733,"58609":20746,"58610":21131,"58611":21132,"58612":21233,"58613":21231,"58614":22088,"58615":22082,"58616":22092,"58617":22069,"58618":22081,"58619":22090,"58620":22089,"58621":22086,"58622":22104,"58688":22106,"58689":22080,"58690":22067,"58691":22077,"58692":22060,"58693":22078,"58694":22072,"58695":22058,"58696":22074,"58697":22298,"58698":22699,"58699":22685,"58700":22705,"58701":22688,"58702":22691,"58703":22703,"58704":22700,"58705":22693,"58706":22689,"58707":22783,"58708":23295,"58709":23284,"58710":23293,"58711":23287,"58712":23286,"58713":23299,"58714":23288,"58715":23298,"58716":23289,"58717":23297,"58718":23303,"58719":23301,"58720":23311,"58721":23655,"58722":23961,"58723":23959,"58724":23967,"58725":23954,"58726":23970,"58727":23955,"58728":23957,"58729":23968,"58730":23964,"58731":23969,"58732":23962,"58733":23966,"58734":24169,"58735":24157,"58736":24160,"58737":24156,"58738":32243,"58739":24283,"58740":24286,"58741":24289,"58742":24393,"58743":24498,"58744":24971,"58745":24963,"58746":24953,"58747":25009,"58748":25008,"58749":24994,"58750":24969,"58785":24987,"58786":24979,"58787":25007,"58788":25005,"58789":24991,"58790":24978,"58791":25002,"58792":24993,"58793":24973,"58794":24934,"58795":25011,"58796":25133,"58797":25710,"58798":25712,"58799":25750,"58800":25760,"58801":25733,"58802":25751,"58803":25756,"58804":25743,"58805":25739,"58806":25738,"58807":25740,"58808":25763,"58809":25759,"58810":25704,"58811":25777,"58812":25752,"58813":25974,"58814":25978,"58815":25977,"58816":25979,"58817":26034,"58818":26035,"58819":26293,"58820":26288,"58821":26281,"58822":26290,"58823":26295,"58824":26282,"58825":26287,"58826":27136,"58827":27142,"58828":27159,"58829":27109,"58830":27128,"58831":27157,"58832":27121,"58833":27108,"58834":27168,"58835":27135,"58836":27116,"58837":27106,"58838":27163,"58839":27165,"58840":27134,"58841":27175,"58842":27122,"58843":27118,"58844":27156,"58845":27127,"58846":27111,"58847":27200,"58848":27144,"58849":27110,"58850":27131,"58851":27149,"58852":27132,"58853":27115,"58854":27145,"58855":27140,"58856":27160,"58857":27173,"58858":27151,"58859":27126,"58860":27174,"58861":27143,"58862":27124,"58863":27158,"58864":27473,"58865":27557,"58866":27555,"58867":27554,"58868":27558,"58869":27649,"58870":27648,"58871":27647,"58872":27650,"58873":28481,"58874":28454,"58875":28542,"58876":28551,"58877":28614,"58878":28562,"58944":28557,"58945":28553,"58946":28556,"58947":28514,"58948":28495,"58949":28549,"58950":28506,"58951":28566,"58952":28534,"58953":28524,"58954":28546,"58955":28501,"58956":28530,"58957":28498,"58958":28496,"58959":28503,"58960":28564,"58961":28563,"58962":28509,"58963":28416,"58964":28513,"58965":28523,"58966":28541,"58967":28519,"58968":28560,"58969":28499,"58970":28555,"58971":28521,"58972":28543,"58973":28565,"58974":28515,"58975":28535,"58976":28522,"58977":28539,"58978":29106,"58979":29103,"58980":29083,"58981":29104,"58982":29088,"58983":29082,"58984":29097,"58985":29109,"58986":29085,"58987":29093,"58988":29086,"58989":29092,"58990":29089,"58991":29098,"58992":29084,"58993":29095,"58994":29107,"58995":29336,"58996":29338,"58997":29528,"58998":29522,"58999":29534,"59000":29535,"59001":29536,"59002":29533,"59003":29531,"59004":29537,"59005":29530,"59006":29529,"59041":29538,"59042":29831,"59043":29833,"59044":29834,"59045":29830,"59046":29825,"59047":29821,"59048":29829,"59049":29832,"59050":29820,"59051":29817,"59052":29960,"59053":29959,"59054":30078,"59055":30245,"59056":30238,"59057":30233,"59058":30237,"59059":30236,"59060":30243,"59061":30234,"59062":30248,"59063":30235,"59064":30364,"59065":30365,"59066":30366,"59067":30363,"59068":30605,"59069":30607,"59070":30601,"59071":30600,"59072":30925,"59073":30907,"59074":30927,"59075":30924,"59076":30929,"59077":30926,"59078":30932,"59079":30920,"59080":30915,"59081":30916,"59082":30921,"59083":31130,"59084":31137,"59085":31136,"59086":31132,"59087":31138,"59088":31131,"59089":27510,"59090":31289,"59091":31410,"59092":31412,"59093":31411,"59094":31671,"59095":31691,"59096":31678,"59097":31660,"59098":31694,"59099":31663,"59100":31673,"59101":31690,"59102":31669,"59103":31941,"59104":31944,"59105":31948,"59106":31947,"59107":32247,"59108":32219,"59109":32234,"59110":32231,"59111":32215,"59112":32225,"59113":32259,"59114":32250,"59115":32230,"59116":32246,"59117":32241,"59118":32240,"59119":32238,"59120":32223,"59121":32630,"59122":32684,"59123":32688,"59124":32685,"59125":32749,"59126":32747,"59127":32746,"59128":32748,"59129":32742,"59130":32744,"59131":32868,"59132":32871,"59133":33187,"59134":33183,"59200":33182,"59201":33173,"59202":33186,"59203":33177,"59204":33175,"59205":33302,"59206":33359,"59207":33363,"59208":33362,"59209":33360,"59210":33358,"59211":33361,"59212":34084,"59213":34107,"59214":34063,"59215":34048,"59216":34089,"59217":34062,"59218":34057,"59219":34061,"59220":34079,"59221":34058,"59222":34087,"59223":34076,"59224":34043,"59225":34091,"59226":34042,"59227":34056,"59228":34060,"59229":34036,"59230":34090,"59231":34034,"59232":34069,"59233":34039,"59234":34027,"59235":34035,"59236":34044,"59237":34066,"59238":34026,"59239":34025,"59240":34070,"59241":34046,"59242":34088,"59243":34077,"59244":34094,"59245":34050,"59246":34045,"59247":34078,"59248":34038,"59249":34097,"59250":34086,"59251":34023,"59252":34024,"59253":34032,"59254":34031,"59255":34041,"59256":34072,"59257":34080,"59258":34096,"59259":34059,"59260":34073,"59261":34095,"59262":34402,"59297":34646,"59298":34659,"59299":34660,"59300":34679,"59301":34785,"59302":34675,"59303":34648,"59304":34644,"59305":34651,"59306":34642,"59307":34657,"59308":34650,"59309":34641,"59310":34654,"59311":34669,"59312":34666,"59313":34640,"59314":34638,"59315":34655,"59316":34653,"59317":34671,"59318":34668,"59319":34682,"59320":34670,"59321":34652,"59322":34661,"59323":34639,"59324":34683,"59325":34677,"59326":34658,"59327":34663,"59328":34665,"59329":34906,"59330":35077,"59331":35084,"59332":35092,"59333":35083,"59334":35095,"59335":35096,"59336":35097,"59337":35078,"59338":35094,"59339":35089,"59340":35086,"59341":35081,"59342":35234,"59343":35236,"59344":35235,"59345":35309,"59346":35312,"59347":35308,"59348":35535,"59349":35526,"59350":35512,"59351":35539,"59352":35537,"59353":35540,"59354":35541,"59355":35515,"59356":35543,"59357":35518,"59358":35520,"59359":35525,"59360":35544,"59361":35523,"59362":35514,"59363":35517,"59364":35545,"59365":35902,"59366":35917,"59367":35983,"59368":36069,"59369":36063,"59370":36057,"59371":36072,"59372":36058,"59373":36061,"59374":36071,"59375":36256,"59376":36252,"59377":36257,"59378":36251,"59379":36384,"59380":36387,"59381":36389,"59382":36388,"59383":36398,"59384":36373,"59385":36379,"59386":36374,"59387":36369,"59388":36377,"59389":36390,"59390":36391,"59456":36372,"59457":36370,"59458":36376,"59459":36371,"59460":36380,"59461":36375,"59462":36378,"59463":36652,"59464":36644,"59465":36632,"59466":36634,"59467":36640,"59468":36643,"59469":36630,"59470":36631,"59471":36979,"59472":36976,"59473":36975,"59474":36967,"59475":36971,"59476":37167,"59477":37163,"59478":37161,"59479":37162,"59480":37170,"59481":37158,"59482":37166,"59483":37253,"59484":37254,"59485":37258,"59486":37249,"59487":37250,"59488":37252,"59489":37248,"59490":37584,"59491":37571,"59492":37572,"59493":37568,"59494":37593,"59495":37558,"59496":37583,"59497":37617,"59498":37599,"59499":37592,"59500":37609,"59501":37591,"59502":37597,"59503":37580,"59504":37615,"59505":37570,"59506":37608,"59507":37578,"59508":37576,"59509":37582,"59510":37606,"59511":37581,"59512":37589,"59513":37577,"59514":37600,"59515":37598,"59516":37607,"59517":37585,"59518":37587,"59553":37557,"59554":37601,"59555":37574,"59556":37556,"59557":38268,"59558":38316,"59559":38315,"59560":38318,"59561":38320,"59562":38564,"59563":38562,"59564":38611,"59565":38661,"59566":38664,"59567":38658,"59568":38746,"59569":38794,"59570":38798,"59571":38792,"59572":38864,"59573":38863,"59574":38942,"59575":38941,"59576":38950,"59577":38953,"59578":38952,"59579":38944,"59580":38939,"59581":38951,"59582":39090,"59583":39176,"59584":39162,"59585":39185,"59586":39188,"59587":39190,"59588":39191,"59589":39189,"59590":39388,"59591":39373,"59592":39375,"59593":39379,"59594":39380,"59595":39374,"59596":39369,"59597":39382,"59598":39384,"59599":39371,"59600":39383,"59601":39372,"59602":39603,"59603":39660,"59604":39659,"59605":39667,"59606":39666,"59607":39665,"59608":39750,"59609":39747,"59610":39783,"59611":39796,"59612":39793,"59613":39782,"59614":39798,"59615":39797,"59616":39792,"59617":39784,"59618":39780,"59619":39788,"59620":40188,"59621":40186,"59622":40189,"59623":40191,"59624":40183,"59625":40199,"59626":40192,"59627":40185,"59628":40187,"59629":40200,"59630":40197,"59631":40196,"59632":40579,"59633":40659,"59634":40719,"59635":40720,"59636":20764,"59637":20755,"59638":20759,"59639":20762,"59640":20753,"59641":20958,"59642":21300,"59643":21473,"59644":22128,"59645":22112,"59646":22126,"59712":22131,"59713":22118,"59714":22115,"59715":22125,"59716":22130,"59717":22110,"59718":22135,"59719":22300,"59720":22299,"59721":22728,"59722":22717,"59723":22729,"59724":22719,"59725":22714,"59726":22722,"59727":22716,"59728":22726,"59729":23319,"59730":23321,"59731":23323,"59732":23329,"59733":23316,"59734":23315,"59735":23312,"59736":23318,"59737":23336,"59738":23322,"59739":23328,"59740":23326,"59741":23535,"59742":23980,"59743":23985,"59744":23977,"59745":23975,"59746":23989,"59747":23984,"59748":23982,"59749":23978,"59750":23976,"59751":23986,"59752":23981,"59753":23983,"59754":23988,"59755":24167,"59756":24168,"59757":24166,"59758":24175,"59759":24297,"59760":24295,"59761":24294,"59762":24296,"59763":24293,"59764":24395,"59765":24508,"59766":24989,"59767":25000,"59768":24982,"59769":25029,"59770":25012,"59771":25030,"59772":25025,"59773":25036,"59774":25018,"59809":25023,"59810":25016,"59811":24972,"59812":25815,"59813":25814,"59814":25808,"59815":25807,"59816":25801,"59817":25789,"59818":25737,"59819":25795,"59820":25819,"59821":25843,"59822":25817,"59823":25907,"59824":25983,"59825":25980,"59826":26018,"59827":26312,"59828":26302,"59829":26304,"59830":26314,"59831":26315,"59832":26319,"59833":26301,"59834":26299,"59835":26298,"59836":26316,"59837":26403,"59838":27188,"59839":27238,"59840":27209,"59841":27239,"59842":27186,"59843":27240,"59844":27198,"59845":27229,"59846":27245,"59847":27254,"59848":27227,"59849":27217,"59850":27176,"59851":27226,"59852":27195,"59853":27199,"59854":27201,"59855":27242,"59856":27236,"59857":27216,"59858":27215,"59859":27220,"59860":27247,"59861":27241,"59862":27232,"59863":27196,"59864":27230,"59865":27222,"59866":27221,"59867":27213,"59868":27214,"59869":27206,"59870":27477,"59871":27476,"59872":27478,"59873":27559,"59874":27562,"59875":27563,"59876":27592,"59877":27591,"59878":27652,"59879":27651,"59880":27654,"59881":28589,"59882":28619,"59883":28579,"59884":28615,"59885":28604,"59886":28622,"59887":28616,"59888":28510,"59889":28612,"59890":28605,"59891":28574,"59892":28618,"59893":28584,"59894":28676,"59895":28581,"59896":28590,"59897":28602,"59898":28588,"59899":28586,"59900":28623,"59901":28607,"59902":28600,"59968":28578,"59969":28617,"59970":28587,"59971":28621,"59972":28591,"59973":28594,"59974":28592,"59975":29125,"59976":29122,"59977":29119,"59978":29112,"59979":29142,"59980":29120,"59981":29121,"59982":29131,"59983":29140,"59984":29130,"59985":29127,"59986":29135,"59987":29117,"59988":29144,"59989":29116,"59990":29126,"59991":29146,"59992":29147,"59993":29341,"59994":29342,"59995":29545,"59996":29542,"59997":29543,"59998":29548,"59999":29541,"60000":29547,"60001":29546,"60002":29823,"60003":29850,"60004":29856,"60005":29844,"60006":29842,"60007":29845,"60008":29857,"60009":29963,"60010":30080,"60011":30255,"60012":30253,"60013":30257,"60014":30269,"60015":30259,"60016":30268,"60017":30261,"60018":30258,"60019":30256,"60020":30395,"60021":30438,"60022":30618,"60023":30621,"60024":30625,"60025":30620,"60026":30619,"60027":30626,"60028":30627,"60029":30613,"60030":30617,"60065":30615,"60066":30941,"60067":30953,"60068":30949,"60069":30954,"60070":30942,"60071":30947,"60072":30939,"60073":30945,"60074":30946,"60075":30957,"60076":30943,"60077":30944,"60078":31140,"60079":31300,"60080":31304,"60081":31303,"60082":31414,"60083":31416,"60084":31413,"60085":31409,"60086":31415,"60087":31710,"60088":31715,"60089":31719,"60090":31709,"60091":31701,"60092":31717,"60093":31706,"60094":31720,"60095":31737,"60096":31700,"60097":31722,"60098":31714,"60099":31708,"60100":31723,"60101":31704,"60102":31711,"60103":31954,"60104":31956,"60105":31959,"60106":31952,"60107":31953,"60108":32274,"60109":32289,"60110":32279,"60111":32268,"60112":32287,"60113":32288,"60114":32275,"60115":32270,"60116":32284,"60117":32277,"60118":32282,"60119":32290,"60120":32267,"60121":32271,"60122":32278,"60123":32269,"60124":32276,"60125":32293,"60126":32292,"60127":32579,"60128":32635,"60129":32636,"60130":32634,"60131":32689,"60132":32751,"60133":32810,"60134":32809,"60135":32876,"60136":33201,"60137":33190,"60138":33198,"60139":33209,"60140":33205,"60141":33195,"60142":33200,"60143":33196,"60144":33204,"60145":33202,"60146":33207,"60147":33191,"60148":33266,"60149":33365,"60150":33366,"60151":33367,"60152":34134,"60153":34117,"60154":34155,"60155":34125,"60156":34131,"60157":34145,"60158":34136,"60224":34112,"60225":34118,"60226":34148,"60227":34113,"60228":34146,"60229":34116,"60230":34129,"60231":34119,"60232":34147,"60233":34110,"60234":34139,"60235":34161,"60236":34126,"60237":34158,"60238":34165,"60239":34133,"60240":34151,"60241":34144,"60242":34188,"60243":34150,"60244":34141,"60245":34132,"60246":34149,"60247":34156,"60248":34403,"60249":34405,"60250":34404,"60251":34715,"60252":34703,"60253":34711,"60254":34707,"60255":34706,"60256":34696,"60257":34689,"60258":34710,"60259":34712,"60260":34681,"60261":34695,"60262":34723,"60263":34693,"60264":34704,"60265":34705,"60266":34717,"60267":34692,"60268":34708,"60269":34716,"60270":34714,"60271":34697,"60272":35102,"60273":35110,"60274":35120,"60275":35117,"60276":35118,"60277":35111,"60278":35121,"60279":35106,"60280":35113,"60281":35107,"60282":35119,"60283":35116,"60284":35103,"60285":35313,"60286":35552,"60321":35554,"60322":35570,"60323":35572,"60324":35573,"60325":35549,"60326":35604,"60327":35556,"60328":35551,"60329":35568,"60330":35528,"60331":35550,"60332":35553,"60333":35560,"60334":35583,"60335":35567,"60336":35579,"60337":35985,"60338":35986,"60339":35984,"60340":36085,"60341":36078,"60342":36081,"60343":36080,"60344":36083,"60345":36204,"60346":36206,"60347":36261,"60348":36263,"60349":36403,"60350":36414,"60351":36408,"60352":36416,"60353":36421,"60354":36406,"60355":36412,"60356":36413,"60357":36417,"60358":36400,"60359":36415,"60360":36541,"60361":36662,"60362":36654,"60363":36661,"60364":36658,"60365":36665,"60366":36663,"60367":36660,"60368":36982,"60369":36985,"60370":36987,"60371":36998,"60372":37114,"60373":37171,"60374":37173,"60375":37174,"60376":37267,"60377":37264,"60378":37265,"60379":37261,"60380":37263,"60381":37671,"60382":37662,"60383":37640,"60384":37663,"60385":37638,"60386":37647,"60387":37754,"60388":37688,"60389":37692,"60390":37659,"60391":37667,"60392":37650,"60393":37633,"60394":37702,"60395":37677,"60396":37646,"60397":37645,"60398":37579,"60399":37661,"60400":37626,"60401":37669,"60402":37651,"60403":37625,"60404":37623,"60405":37684,"60406":37634,"60407":37668,"60408":37631,"60409":37673,"60410":37689,"60411":37685,"60412":37674,"60413":37652,"60414":37644,"60480":37643,"60481":37630,"60482":37641,"60483":37632,"60484":37627,"60485":37654,"60486":38332,"60487":38349,"60488":38334,"60489":38329,"60490":38330,"60491":38326,"60492":38335,"60493":38325,"60494":38333,"60495":38569,"60496":38612,"60497":38667,"60498":38674,"60499":38672,"60500":38809,"60501":38807,"60502":38804,"60503":38896,"60504":38904,"60505":38965,"60506":38959,"60507":38962,"60508":39204,"60509":39199,"60510":39207,"60511":39209,"60512":39326,"60513":39406,"60514":39404,"60515":39397,"60516":39396,"60517":39408,"60518":39395,"60519":39402,"60520":39401,"60521":39399,"60522":39609,"60523":39615,"60524":39604,"60525":39611,"60526":39670,"60527":39674,"60528":39673,"60529":39671,"60530":39731,"60531":39808,"60532":39813,"60533":39815,"60534":39804,"60535":39806,"60536":39803,"60537":39810,"60538":39827,"60539":39826,"60540":39824,"60541":39802,"60542":39829,"60577":39805,"60578":39816,"60579":40229,"60580":40215,"60581":40224,"60582":40222,"60583":40212,"60584":40233,"60585":40221,"60586":40216,"60587":40226,"60588":40208,"60589":40217,"60590":40223,"60591":40584,"60592":40582,"60593":40583,"60594":40622,"60595":40621,"60596":40661,"60597":40662,"60598":40698,"60599":40722,"60600":40765,"60601":20774,"60602":20773,"60603":20770,"60604":20772,"60605":20768,"60606":20777,"60607":21236,"60608":22163,"60609":22156,"60610":22157,"60611":22150,"60612":22148,"60613":22147,"60614":22142,"60615":22146,"60616":22143,"60617":22145,"60618":22742,"60619":22740,"60620":22735,"60621":22738,"60622":23341,"60623":23333,"60624":23346,"60625":23331,"60626":23340,"60627":23335,"60628":23334,"60629":23343,"60630":23342,"60631":23419,"60632":23537,"60633":23538,"60634":23991,"60635":24172,"60636":24170,"60637":24510,"60638":24507,"60639":25027,"60640":25013,"60641":25020,"60642":25063,"60643":25056,"60644":25061,"60645":25060,"60646":25064,"60647":25054,"60648":25839,"60649":25833,"60650":25827,"60651":25835,"60652":25828,"60653":25832,"60654":25985,"60655":25984,"60656":26038,"60657":26074,"60658":26322,"60659":27277,"60660":27286,"60661":27265,"60662":27301,"60663":27273,"60664":27295,"60665":27291,"60666":27297,"60667":27294,"60668":27271,"60669":27283,"60670":27278,"60736":27285,"60737":27267,"60738":27304,"60739":27300,"60740":27281,"60741":27263,"60742":27302,"60743":27290,"60744":27269,"60745":27276,"60746":27282,"60747":27483,"60748":27565,"60749":27657,"60750":28620,"60751":28585,"60752":28660,"60753":28628,"60754":28643,"60755":28636,"60756":28653,"60757":28647,"60758":28646,"60759":28638,"60760":28658,"60761":28637,"60762":28642,"60763":28648,"60764":29153,"60765":29169,"60766":29160,"60767":29170,"60768":29156,"60769":29168,"60770":29154,"60771":29555,"60772":29550,"60773":29551,"60774":29847,"60775":29874,"60776":29867,"60777":29840,"60778":29866,"60779":29869,"60780":29873,"60781":29861,"60782":29871,"60783":29968,"60784":29969,"60785":29970,"60786":29967,"60787":30084,"60788":30275,"60789":30280,"60790":30281,"60791":30279,"60792":30372,"60793":30441,"60794":30645,"60795":30635,"60796":30642,"60797":30647,"60798":30646,"60833":30644,"60834":30641,"60835":30632,"60836":30704,"60837":30963,"60838":30973,"60839":30978,"60840":30971,"60841":30972,"60842":30962,"60843":30981,"60844":30969,"60845":30974,"60846":30980,"60847":31147,"60848":31144,"60849":31324,"60850":31323,"60851":31318,"60852":31320,"60853":31316,"60854":31322,"60855":31422,"60856":31424,"60857":31425,"60858":31749,"60859":31759,"60860":31730,"60861":31744,"60862":31743,"60863":31739,"60864":31758,"60865":31732,"60866":31755,"60867":31731,"60868":31746,"60869":31753,"60870":31747,"60871":31745,"60872":31736,"60873":31741,"60874":31750,"60875":31728,"60876":31729,"60877":31760,"60878":31754,"60879":31976,"60880":32301,"60881":32316,"60882":32322,"60883":32307,"60884":38984,"60885":32312,"60886":32298,"60887":32329,"60888":32320,"60889":32327,"60890":32297,"60891":32332,"60892":32304,"60893":32315,"60894":32310,"60895":32324,"60896":32314,"60897":32581,"60898":32639,"60899":32638,"60900":32637,"60901":32756,"60902":32754,"60903":32812,"60904":33211,"60905":33220,"60906":33228,"60907":33226,"60908":33221,"60909":33223,"60910":33212,"60911":33257,"60912":33371,"60913":33370,"60914":33372,"60915":34179,"60916":34176,"60917":34191,"60918":34215,"60919":34197,"60920":34208,"60921":34187,"60922":34211,"60923":34171,"60924":34212,"60925":34202,"60926":34206,"60992":34167,"60993":34172,"60994":34185,"60995":34209,"60996":34170,"60997":34168,"60998":34135,"60999":34190,"61000":34198,"61001":34182,"61002":34189,"61003":34201,"61004":34205,"61005":34177,"61006":34210,"61007":34178,"61008":34184,"61009":34181,"61010":34169,"61011":34166,"61012":34200,"61013":34192,"61014":34207,"61015":34408,"61016":34750,"61017":34730,"61018":34733,"61019":34757,"61020":34736,"61021":34732,"61022":34745,"61023":34741,"61024":34748,"61025":34734,"61026":34761,"61027":34755,"61028":34754,"61029":34764,"61030":34743,"61031":34735,"61032":34756,"61033":34762,"61034":34740,"61035":34742,"61036":34751,"61037":34744,"61038":34749,"61039":34782,"61040":34738,"61041":35125,"61042":35123,"61043":35132,"61044":35134,"61045":35137,"61046":35154,"61047":35127,"61048":35138,"61049":35245,"61050":35247,"61051":35246,"61052":35314,"61053":35315,"61054":35614,"61089":35608,"61090":35606,"61091":35601,"61092":35589,"61093":35595,"61094":35618,"61095":35599,"61096":35602,"61097":35605,"61098":35591,"61099":35597,"61100":35592,"61101":35590,"61102":35612,"61103":35603,"61104":35610,"61105":35919,"61106":35952,"61107":35954,"61108":35953,"61109":35951,"61110":35989,"61111":35988,"61112":36089,"61113":36207,"61114":36430,"61115":36429,"61116":36435,"61117":36432,"61118":36428,"61119":36423,"61120":36675,"61121":36672,"61122":36997,"61123":36990,"61124":37176,"61125":37274,"61126":37282,"61127":37275,"61128":37273,"61129":37279,"61130":37281,"61131":37277,"61132":37280,"61133":37793,"61134":37763,"61135":37807,"61136":37732,"61137":37718,"61138":37703,"61139":37756,"61140":37720,"61141":37724,"61142":37750,"61143":37705,"61144":37712,"61145":37713,"61146":37728,"61147":37741,"61148":37775,"61149":37708,"61150":37738,"61151":37753,"61152":37719,"61153":37717,"61154":37714,"61155":37711,"61156":37745,"61157":37751,"61158":37755,"61159":37729,"61160":37726,"61161":37731,"61162":37735,"61163":37760,"61164":37710,"61165":37721,"61166":38343,"61167":38336,"61168":38345,"61169":38339,"61170":38341,"61171":38327,"61172":38574,"61173":38576,"61174":38572,"61175":38688,"61176":38687,"61177":38680,"61178":38685,"61179":38681,"61180":38810,"61181":38817,"61182":38812,"61248":38814,"61249":38813,"61250":38869,"61251":38868,"61252":38897,"61253":38977,"61254":38980,"61255":38986,"61256":38985,"61257":38981,"61258":38979,"61259":39205,"61260":39211,"61261":39212,"61262":39210,"61263":39219,"61264":39218,"61265":39215,"61266":39213,"61267":39217,"61268":39216,"61269":39320,"61270":39331,"61271":39329,"61272":39426,"61273":39418,"61274":39412,"61275":39415,"61276":39417,"61277":39416,"61278":39414,"61279":39419,"61280":39421,"61281":39422,"61282":39420,"61283":39427,"61284":39614,"61285":39678,"61286":39677,"61287":39681,"61288":39676,"61289":39752,"61290":39834,"61291":39848,"61292":39838,"61293":39835,"61294":39846,"61295":39841,"61296":39845,"61297":39844,"61298":39814,"61299":39842,"61300":39840,"61301":39855,"61302":40243,"61303":40257,"61304":40295,"61305":40246,"61306":40238,"61307":40239,"61308":40241,"61309":40248,"61310":40240,"61345":40261,"61346":40258,"61347":40259,"61348":40254,"61349":40247,"61350":40256,"61351":40253,"61352":32757,"61353":40237,"61354":40586,"61355":40585,"61356":40589,"61357":40624,"61358":40648,"61359":40666,"61360":40699,"61361":40703,"61362":40740,"61363":40739,"61364":40738,"61365":40788,"61366":40864,"61367":20785,"61368":20781,"61369":20782,"61370":22168,"61371":22172,"61372":22167,"61373":22170,"61374":22173,"61375":22169,"61376":22896,"61377":23356,"61378":23657,"61379":23658,"61380":24000,"61381":24173,"61382":24174,"61383":25048,"61384":25055,"61385":25069,"61386":25070,"61387":25073,"61388":25066,"61389":25072,"61390":25067,"61391":25046,"61392":25065,"61393":25855,"61394":25860,"61395":25853,"61396":25848,"61397":25857,"61398":25859,"61399":25852,"61400":26004,"61401":26075,"61402":26330,"61403":26331,"61404":26328,"61405":27333,"61406":27321,"61407":27325,"61408":27361,"61409":27334,"61410":27322,"61411":27318,"61412":27319,"61413":27335,"61414":27316,"61415":27309,"61416":27486,"61417":27593,"61418":27659,"61419":28679,"61420":28684,"61421":28685,"61422":28673,"61423":28677,"61424":28692,"61425":28686,"61426":28671,"61427":28672,"61428":28667,"61429":28710,"61430":28668,"61431":28663,"61432":28682,"61433":29185,"61434":29183,"61435":29177,"61436":29187,"61437":29181,"61438":29558,"61504":29880,"61505":29888,"61506":29877,"61507":29889,"61508":29886,"61509":29878,"61510":29883,"61511":29890,"61512":29972,"61513":29971,"61514":30300,"61515":30308,"61516":30297,"61517":30288,"61518":30291,"61519":30295,"61520":30298,"61521":30374,"61522":30397,"61523":30444,"61524":30658,"61525":30650,"61526":30975,"61527":30988,"61528":30995,"61529":30996,"61530":30985,"61531":30992,"61532":30994,"61533":30993,"61534":31149,"61535":31148,"61536":31327,"61537":31772,"61538":31785,"61539":31769,"61540":31776,"61541":31775,"61542":31789,"61543":31773,"61544":31782,"61545":31784,"61546":31778,"61547":31781,"61548":31792,"61549":32348,"61550":32336,"61551":32342,"61552":32355,"61553":32344,"61554":32354,"61555":32351,"61556":32337,"61557":32352,"61558":32343,"61559":32339,"61560":32693,"61561":32691,"61562":32759,"61563":32760,"61564":32885,"61565":33233,"61566":33234,"61601":33232,"61602":33375,"61603":33374,"61604":34228,"61605":34246,"61606":34240,"61607":34243,"61608":34242,"61609":34227,"61610":34229,"61611":34237,"61612":34247,"61613":34244,"61614":34239,"61615":34251,"61616":34254,"61617":34248,"61618":34245,"61619":34225,"61620":34230,"61621":34258,"61622":34340,"61623":34232,"61624":34231,"61625":34238,"61626":34409,"61627":34791,"61628":34790,"61629":34786,"61630":34779,"61631":34795,"61632":34794,"61633":34789,"61634":34783,"61635":34803,"61636":34788,"61637":34772,"61638":34780,"61639":34771,"61640":34797,"61641":34776,"61642":34787,"61643":34724,"61644":34775,"61645":34777,"61646":34817,"61647":34804,"61648":34792,"61649":34781,"61650":35155,"61651":35147,"61652":35151,"61653":35148,"61654":35142,"61655":35152,"61656":35153,"61657":35145,"61658":35626,"61659":35623,"61660":35619,"61661":35635,"61662":35632,"61663":35637,"61664":35655,"61665":35631,"61666":35644,"61667":35646,"61668":35633,"61669":35621,"61670":35639,"61671":35622,"61672":35638,"61673":35630,"61674":35620,"61675":35643,"61676":35645,"61677":35642,"61678":35906,"61679":35957,"61680":35993,"61681":35992,"61682":35991,"61683":36094,"61684":36100,"61685":36098,"61686":36096,"61687":36444,"61688":36450,"61689":36448,"61690":36439,"61691":36438,"61692":36446,"61693":36453,"61694":36455,"61760":36443,"61761":36442,"61762":36449,"61763":36445,"61764":36457,"61765":36436,"61766":36678,"61767":36679,"61768":36680,"61769":36683,"61770":37160,"61771":37178,"61772":37179,"61773":37182,"61774":37288,"61775":37285,"61776":37287,"61777":37295,"61778":37290,"61779":37813,"61780":37772,"61781":37778,"61782":37815,"61783":37787,"61784":37789,"61785":37769,"61786":37799,"61787":37774,"61788":37802,"61789":37790,"61790":37798,"61791":37781,"61792":37768,"61793":37785,"61794":37791,"61795":37773,"61796":37809,"61797":37777,"61798":37810,"61799":37796,"61800":37800,"61801":37812,"61802":37795,"61803":37797,"61804":38354,"61805":38355,"61806":38353,"61807":38579,"61808":38615,"61809":38618,"61810":24002,"61811":38623,"61812":38616,"61813":38621,"61814":38691,"61815":38690,"61816":38693,"61817":38828,"61818":38830,"61819":38824,"61820":38827,"61821":38820,"61822":38826,"61857":38818,"61858":38821,"61859":38871,"61860":38873,"61861":38870,"61862":38872,"61863":38906,"61864":38992,"61865":38993,"61866":38994,"61867":39096,"61868":39233,"61869":39228,"61870":39226,"61871":39439,"61872":39435,"61873":39433,"61874":39437,"61875":39428,"61876":39441,"61877":39434,"61878":39429,"61879":39431,"61880":39430,"61881":39616,"61882":39644,"61883":39688,"61884":39684,"61885":39685,"61886":39721,"61887":39733,"61888":39754,"61889":39756,"61890":39755,"61891":39879,"61892":39878,"61893":39875,"61894":39871,"61895":39873,"61896":39861,"61897":39864,"61898":39891,"61899":39862,"61900":39876,"61901":39865,"61902":39869,"61903":40284,"61904":40275,"61905":40271,"61906":40266,"61907":40283,"61908":40267,"61909":40281,"61910":40278,"61911":40268,"61912":40279,"61913":40274,"61914":40276,"61915":40287,"61916":40280,"61917":40282,"61918":40590,"61919":40588,"61920":40671,"61921":40705,"61922":40704,"61923":40726,"61924":40741,"61925":40747,"61926":40746,"61927":40745,"61928":40744,"61929":40780,"61930":40789,"61931":20788,"61932":20789,"61933":21142,"61934":21239,"61935":21428,"61936":22187,"61937":22189,"61938":22182,"61939":22183,"61940":22186,"61941":22188,"61942":22746,"61943":22749,"61944":22747,"61945":22802,"61946":23357,"61947":23358,"61948":23359,"61949":24003,"61950":24176,"62016":24511,"62017":25083,"62018":25863,"62019":25872,"62020":25869,"62021":25865,"62022":25868,"62023":25870,"62024":25988,"62025":26078,"62026":26077,"62027":26334,"62028":27367,"62029":27360,"62030":27340,"62031":27345,"62032":27353,"62033":27339,"62034":27359,"62035":27356,"62036":27344,"62037":27371,"62038":27343,"62039":27341,"62040":27358,"62041":27488,"62042":27568,"62043":27660,"62044":28697,"62045":28711,"62046":28704,"62047":28694,"62048":28715,"62049":28705,"62050":28706,"62051":28707,"62052":28713,"62053":28695,"62054":28708,"62055":28700,"62056":28714,"62057":29196,"62058":29194,"62059":29191,"62060":29186,"62061":29189,"62062":29349,"62063":29350,"62064":29348,"62065":29347,"62066":29345,"62067":29899,"62068":29893,"62069":29879,"62070":29891,"62071":29974,"62072":30304,"62073":30665,"62074":30666,"62075":30660,"62076":30705,"62077":31005,"62078":31003,"62113":31009,"62114":31004,"62115":30999,"62116":31006,"62117":31152,"62118":31335,"62119":31336,"62120":31795,"62121":31804,"62122":31801,"62123":31788,"62124":31803,"62125":31980,"62126":31978,"62127":32374,"62128":32373,"62129":32376,"62130":32368,"62131":32375,"62132":32367,"62133":32378,"62134":32370,"62135":32372,"62136":32360,"62137":32587,"62138":32586,"62139":32643,"62140":32646,"62141":32695,"62142":32765,"62143":32766,"62144":32888,"62145":33239,"62146":33237,"62147":33380,"62148":33377,"62149":33379,"62150":34283,"62151":34289,"62152":34285,"62153":34265,"62154":34273,"62155":34280,"62156":34266,"62157":34263,"62158":34284,"62159":34290,"62160":34296,"62161":34264,"62162":34271,"62163":34275,"62164":34268,"62165":34257,"62166":34288,"62167":34278,"62168":34287,"62169":34270,"62170":34274,"62171":34816,"62172":34810,"62173":34819,"62174":34806,"62175":34807,"62176":34825,"62177":34828,"62178":34827,"62179":34822,"62180":34812,"62181":34824,"62182":34815,"62183":34826,"62184":34818,"62185":35170,"62186":35162,"62187":35163,"62188":35159,"62189":35169,"62190":35164,"62191":35160,"62192":35165,"62193":35161,"62194":35208,"62195":35255,"62196":35254,"62197":35318,"62198":35664,"62199":35656,"62200":35658,"62201":35648,"62202":35667,"62203":35670,"62204":35668,"62205":35659,"62206":35669,"62272":35665,"62273":35650,"62274":35666,"62275":35671,"62276":35907,"62277":35959,"62278":35958,"62279":35994,"62280":36102,"62281":36103,"62282":36105,"62283":36268,"62284":36266,"62285":36269,"62286":36267,"62287":36461,"62288":36472,"62289":36467,"62290":36458,"62291":36463,"62292":36475,"62293":36546,"62294":36690,"62295":36689,"62296":36687,"62297":36688,"62298":36691,"62299":36788,"62300":37184,"62301":37183,"62302":37296,"62303":37293,"62304":37854,"62305":37831,"62306":37839,"62307":37826,"62308":37850,"62309":37840,"62310":37881,"62311":37868,"62312":37836,"62313":37849,"62314":37801,"62315":37862,"62316":37834,"62317":37844,"62318":37870,"62319":37859,"62320":37845,"62321":37828,"62322":37838,"62323":37824,"62324":37842,"62325":37863,"62326":38269,"62327":38362,"62328":38363,"62329":38625,"62330":38697,"62331":38699,"62332":38700,"62333":38696,"62334":38694,"62369":38835,"62370":38839,"62371":38838,"62372":38877,"62373":38878,"62374":38879,"62375":39004,"62376":39001,"62377":39005,"62378":38999,"62379":39103,"62380":39101,"62381":39099,"62382":39102,"62383":39240,"62384":39239,"62385":39235,"62386":39334,"62387":39335,"62388":39450,"62389":39445,"62390":39461,"62391":39453,"62392":39460,"62393":39451,"62394":39458,"62395":39456,"62396":39463,"62397":39459,"62398":39454,"62399":39452,"62400":39444,"62401":39618,"62402":39691,"62403":39690,"62404":39694,"62405":39692,"62406":39735,"62407":39914,"62408":39915,"62409":39904,"62410":39902,"62411":39908,"62412":39910,"62413":39906,"62414":39920,"62415":39892,"62416":39895,"62417":39916,"62418":39900,"62419":39897,"62420":39909,"62421":39893,"62422":39905,"62423":39898,"62424":40311,"62425":40321,"62426":40330,"62427":40324,"62428":40328,"62429":40305,"62430":40320,"62431":40312,"62432":40326,"62433":40331,"62434":40332,"62435":40317,"62436":40299,"62437":40308,"62438":40309,"62439":40304,"62440":40297,"62441":40325,"62442":40307,"62443":40315,"62444":40322,"62445":40303,"62446":40313,"62447":40319,"62448":40327,"62449":40296,"62450":40596,"62451":40593,"62452":40640,"62453":40700,"62454":40749,"62455":40768,"62456":40769,"62457":40781,"62458":40790,"62459":40791,"62460":40792,"62461":21303,"62462":22194,"62528":22197,"62529":22195,"62530":22755,"62531":23365,"62532":24006,"62533":24007,"62534":24302,"62535":24303,"62536":24512,"62537":24513,"62538":25081,"62539":25879,"62540":25878,"62541":25877,"62542":25875,"62543":26079,"62544":26344,"62545":26339,"62546":26340,"62547":27379,"62548":27376,"62549":27370,"62550":27368,"62551":27385,"62552":27377,"62553":27374,"62554":27375,"62555":28732,"62556":28725,"62557":28719,"62558":28727,"62559":28724,"62560":28721,"62561":28738,"62562":28728,"62563":28735,"62564":28730,"62565":28729,"62566":28736,"62567":28731,"62568":28723,"62569":28737,"62570":29203,"62571":29204,"62572":29352,"62573":29565,"62574":29564,"62575":29882,"62576":30379,"62577":30378,"62578":30398,"62579":30445,"62580":30668,"62581":30670,"62582":30671,"62583":30669,"62584":30706,"62585":31013,"62586":31011,"62587":31015,"62588":31016,"62589":31012,"62590":31017,"62625":31154,"62626":31342,"62627":31340,"62628":31341,"62629":31479,"62630":31817,"62631":31816,"62632":31818,"62633":31815,"62634":31813,"62635":31982,"62636":32379,"62637":32382,"62638":32385,"62639":32384,"62640":32698,"62641":32767,"62642":32889,"62643":33243,"62644":33241,"62645":33291,"62646":33384,"62647":33385,"62648":34338,"62649":34303,"62650":34305,"62651":34302,"62652":34331,"62653":34304,"62654":34294,"62655":34308,"62656":34313,"62657":34309,"62658":34316,"62659":34301,"62660":34841,"62661":34832,"62662":34833,"62663":34839,"62664":34835,"62665":34838,"62666":35171,"62667":35174,"62668":35257,"62669":35319,"62670":35680,"62671":35690,"62672":35677,"62673":35688,"62674":35683,"62675":35685,"62676":35687,"62677":35693,"62678":36270,"62679":36486,"62680":36488,"62681":36484,"62682":36697,"62683":36694,"62684":36695,"62685":36693,"62686":36696,"62687":36698,"62688":37005,"62689":37187,"62690":37185,"62691":37303,"62692":37301,"62693":37298,"62694":37299,"62695":37899,"62696":37907,"62697":37883,"62698":37920,"62699":37903,"62700":37908,"62701":37886,"62702":37909,"62703":37904,"62704":37928,"62705":37913,"62706":37901,"62707":37877,"62708":37888,"62709":37879,"62710":37895,"62711":37902,"62712":37910,"62713":37906,"62714":37882,"62715":37897,"62716":37880,"62717":37898,"62718":37887,"62784":37884,"62785":37900,"62786":37878,"62787":37905,"62788":37894,"62789":38366,"62790":38368,"62791":38367,"62792":38702,"62793":38703,"62794":38841,"62795":38843,"62796":38909,"62797":38910,"62798":39008,"62799":39010,"62800":39011,"62801":39007,"62802":39105,"62803":39106,"62804":39248,"62805":39246,"62806":39257,"62807":39244,"62808":39243,"62809":39251,"62810":39474,"62811":39476,"62812":39473,"62813":39468,"62814":39466,"62815":39478,"62816":39465,"62817":39470,"62818":39480,"62819":39469,"62820":39623,"62821":39626,"62822":39622,"62823":39696,"62824":39698,"62825":39697,"62826":39947,"62827":39944,"62828":39927,"62829":39941,"62830":39954,"62831":39928,"62832":40000,"62833":39943,"62834":39950,"62835":39942,"62836":39959,"62837":39956,"62838":39945,"62839":40351,"62840":40345,"62841":40356,"62842":40349,"62843":40338,"62844":40344,"62845":40336,"62846":40347,"62881":40352,"62882":40340,"62883":40348,"62884":40362,"62885":40343,"62886":40353,"62887":40346,"62888":40354,"62889":40360,"62890":40350,"62891":40355,"62892":40383,"62893":40361,"62894":40342,"62895":40358,"62896":40359,"62897":40601,"62898":40603,"62899":40602,"62900":40677,"62901":40676,"62902":40679,"62903":40678,"62904":40752,"62905":40750,"62906":40795,"62907":40800,"62908":40798,"62909":40797,"62910":40793,"62911":40849,"62912":20794,"62913":20793,"62914":21144,"62915":21143,"62916":22211,"62917":22205,"62918":22206,"62919":23368,"62920":23367,"62921":24011,"62922":24015,"62923":24305,"62924":25085,"62925":25883,"62926":27394,"62927":27388,"62928":27395,"62929":27384,"62930":27392,"62931":28739,"62932":28740,"62933":28746,"62934":28744,"62935":28745,"62936":28741,"62937":28742,"62938":29213,"62939":29210,"62940":29209,"62941":29566,"62942":29975,"62943":30314,"62944":30672,"62945":31021,"62946":31025,"62947":31023,"62948":31828,"62949":31827,"62950":31986,"62951":32394,"62952":32391,"62953":32392,"62954":32395,"62955":32390,"62956":32397,"62957":32589,"62958":32699,"62959":32816,"62960":33245,"62961":34328,"62962":34346,"62963":34342,"62964":34335,"62965":34339,"62966":34332,"62967":34329,"62968":34343,"62969":34350,"62970":34337,"62971":34336,"62972":34345,"62973":34334,"62974":34341,"63040":34857,"63041":34845,"63042":34843,"63043":34848,"63044":34852,"63045":34844,"63046":34859,"63047":34890,"63048":35181,"63049":35177,"63050":35182,"63051":35179,"63052":35322,"63053":35705,"63054":35704,"63055":35653,"63056":35706,"63057":35707,"63058":36112,"63059":36116,"63060":36271,"63061":36494,"63062":36492,"63063":36702,"63064":36699,"63065":36701,"63066":37190,"63067":37188,"63068":37189,"63069":37305,"63070":37951,"63071":37947,"63072":37942,"63073":37929,"63074":37949,"63075":37948,"63076":37936,"63077":37945,"63078":37930,"63079":37943,"63080":37932,"63081":37952,"63082":37937,"63083":38373,"63084":38372,"63085":38371,"63086":38709,"63087":38714,"63088":38847,"63089":38881,"63090":39012,"63091":39113,"63092":39110,"63093":39104,"63094":39256,"63095":39254,"63096":39481,"63097":39485,"63098":39494,"63099":39492,"63100":39490,"63101":39489,"63102":39482,"63137":39487,"63138":39629,"63139":39701,"63140":39703,"63141":39704,"63142":39702,"63143":39738,"63144":39762,"63145":39979,"63146":39965,"63147":39964,"63148":39980,"63149":39971,"63150":39976,"63151":39977,"63152":39972,"63153":39969,"63154":40375,"63155":40374,"63156":40380,"63157":40385,"63158":40391,"63159":40394,"63160":40399,"63161":40382,"63162":40389,"63163":40387,"63164":40379,"63165":40373,"63166":40398,"63167":40377,"63168":40378,"63169":40364,"63170":40392,"63171":40369,"63172":40365,"63173":40396,"63174":40371,"63175":40397,"63176":40370,"63177":40570,"63178":40604,"63179":40683,"63180":40686,"63181":40685,"63182":40731,"63183":40728,"63184":40730,"63185":40753,"63186":40782,"63187":40805,"63188":40804,"63189":40850,"63190":20153,"63191":22214,"63192":22213,"63193":22219,"63194":22897,"63195":23371,"63196":23372,"63197":24021,"63198":24017,"63199":24306,"63200":25889,"63201":25888,"63202":25894,"63203":25890,"63204":27403,"63205":27400,"63206":27401,"63207":27661,"63208":28757,"63209":28758,"63210":28759,"63211":28754,"63212":29214,"63213":29215,"63214":29353,"63215":29567,"63216":29912,"63217":29909,"63218":29913,"63219":29911,"63220":30317,"63221":30381,"63222":31029,"63223":31156,"63224":31344,"63225":31345,"63226":31831,"63227":31836,"63228":31833,"63229":31835,"63230":31834,"63296":31988,"63297":31985,"63298":32401,"63299":32591,"63300":32647,"63301":33246,"63302":33387,"63303":34356,"63304":34357,"63305":34355,"63306":34348,"63307":34354,"63308":34358,"63309":34860,"63310":34856,"63311":34854,"63312":34858,"63313":34853,"63314":35185,"63315":35263,"63316":35262,"63317":35323,"63318":35710,"63319":35716,"63320":35714,"63321":35718,"63322":35717,"63323":35711,"63324":36117,"63325":36501,"63326":36500,"63327":36506,"63328":36498,"63329":36496,"63330":36502,"63331":36503,"63332":36704,"63333":36706,"63334":37191,"63335":37964,"63336":37968,"63337":37962,"63338":37963,"63339":37967,"63340":37959,"63341":37957,"63342":37960,"63343":37961,"63344":37958,"63345":38719,"63346":38883,"63347":39018,"63348":39017,"63349":39115,"63350":39252,"63351":39259,"63352":39502,"63353":39507,"63354":39508,"63355":39500,"63356":39503,"63357":39496,"63358":39498,"63393":39497,"63394":39506,"63395":39504,"63396":39632,"63397":39705,"63398":39723,"63399":39739,"63400":39766,"63401":39765,"63402":40006,"63403":40008,"63404":39999,"63405":40004,"63406":39993,"63407":39987,"63408":40001,"63409":39996,"63410":39991,"63411":39988,"63412":39986,"63413":39997,"63414":39990,"63415":40411,"63416":40402,"63417":40414,"63418":40410,"63419":40395,"63420":40400,"63421":40412,"63422":40401,"63423":40415,"63424":40425,"63425":40409,"63426":40408,"63427":40406,"63428":40437,"63429":40405,"63430":40413,"63431":40630,"63432":40688,"63433":40757,"63434":40755,"63435":40754,"63436":40770,"63437":40811,"63438":40853,"63439":40866,"63440":20797,"63441":21145,"63442":22760,"63443":22759,"63444":22898,"63445":23373,"63446":24024,"63447":34863,"63448":24399,"63449":25089,"63450":25091,"63451":25092,"63452":25897,"63453":25893,"63454":26006,"63455":26347,"63456":27409,"63457":27410,"63458":27407,"63459":27594,"63460":28763,"63461":28762,"63462":29218,"63463":29570,"63464":29569,"63465":29571,"63466":30320,"63467":30676,"63468":31847,"63469":31846,"63470":32405,"63471":33388,"63472":34362,"63473":34368,"63474":34361,"63475":34364,"63476":34353,"63477":34363,"63478":34366,"63479":34864,"63480":34866,"63481":34862,"63482":34867,"63483":35190,"63484":35188,"63485":35187,"63486":35326,"63552":35724,"63553":35726,"63554":35723,"63555":35720,"63556":35909,"63557":36121,"63558":36504,"63559":36708,"63560":36707,"63561":37308,"63562":37986,"63563":37973,"63564":37981,"63565":37975,"63566":37982,"63567":38852,"63568":38853,"63569":38912,"63570":39510,"63571":39513,"63572":39710,"63573":39711,"63574":39712,"63575":40018,"63576":40024,"63577":40016,"63578":40010,"63579":40013,"63580":40011,"63581":40021,"63582":40025,"63583":40012,"63584":40014,"63585":40443,"63586":40439,"63587":40431,"63588":40419,"63589":40427,"63590":40440,"63591":40420,"63592":40438,"63593":40417,"63594":40430,"63595":40422,"63596":40434,"63597":40432,"63598":40418,"63599":40428,"63600":40436,"63601":40435,"63602":40424,"63603":40429,"63604":40642,"63605":40656,"63606":40690,"63607":40691,"63608":40710,"63609":40732,"63610":40760,"63611":40759,"63612":40758,"63613":40771,"63614":40783,"63649":40817,"63650":40816,"63651":40814,"63652":40815,"63653":22227,"63654":22221,"63655":23374,"63656":23661,"63657":25901,"63658":26349,"63659":26350,"63660":27411,"63661":28767,"63662":28769,"63663":28765,"63664":28768,"63665":29219,"63666":29915,"63667":29925,"63668":30677,"63669":31032,"63670":31159,"63671":31158,"63672":31850,"63673":32407,"63674":32649,"63675":33389,"63676":34371,"63677":34872,"63678":34871,"63679":34869,"63680":34891,"63681":35732,"63682":35733,"63683":36510,"63684":36511,"63685":36512,"63686":36509,"63687":37310,"63688":37309,"63689":37314,"63690":37995,"63691":37992,"63692":37993,"63693":38629,"63694":38726,"63695":38723,"63696":38727,"63697":38855,"63698":38885,"63699":39518,"63700":39637,"63701":39769,"63702":40035,"63703":40039,"63704":40038,"63705":40034,"63706":40030,"63707":40032,"63708":40450,"63709":40446,"63710":40455,"63711":40451,"63712":40454,"63713":40453,"63714":40448,"63715":40449,"63716":40457,"63717":40447,"63718":40445,"63719":40452,"63720":40608,"63721":40734,"63722":40774,"63723":40820,"63724":40821,"63725":40822,"63726":22228,"63727":25902,"63728":26040,"63729":27416,"63730":27417,"63731":27415,"63732":27418,"63733":28770,"63734":29222,"63735":29354,"63736":30680,"63737":30681,"63738":31033,"63739":31849,"63740":31851,"63741":31990,"63742":32410,"63808":32408,"63809":32411,"63810":32409,"63811":33248,"63812":33249,"63813":34374,"63814":34375,"63815":34376,"63816":35193,"63817":35194,"63818":35196,"63819":35195,"63820":35327,"63821":35736,"63822":35737,"63823":36517,"63824":36516,"63825":36515,"63826":37998,"63827":37997,"63828":37999,"63829":38001,"63830":38003,"63831":38729,"63832":39026,"63833":39263,"63834":40040,"63835":40046,"63836":40045,"63837":40459,"63838":40461,"63839":40464,"63840":40463,"63841":40466,"63842":40465,"63843":40609,"63844":40693,"63845":40713,"63846":40775,"63847":40824,"63848":40827,"63849":40826,"63850":40825,"63851":22302,"63852":28774,"63853":31855,"63854":34876,"63855":36274,"63856":36518,"63857":37315,"63858":38004,"63859":38008,"63860":38006,"63861":38005,"63862":39520,"63863":40052,"63864":40051,"63865":40049,"63866":40053,"63867":40468,"63868":40467,"63869":40694,"63870":40714,"63905":40868,"63906":28776,"63907":28773,"63908":31991,"63909":34410,"63910":34878,"63911":34877,"63912":34879,"63913":35742,"63914":35996,"63915":36521,"63916":36553,"63917":38731,"63918":39027,"63919":39028,"63920":39116,"63921":39265,"63922":39339,"63923":39524,"63924":39526,"63925":39527,"63926":39716,"63927":40469,"63928":40471,"63929":40776,"63930":25095,"63931":27422,"63932":29223,"63933":34380,"63934":36520,"63935":38018,"63936":38016,"63937":38017,"63938":39529,"63939":39528,"63940":39726,"63941":40473,"63942":29225,"63943":34379,"63944":35743,"63945":38019,"63946":40057,"63947":40631,"63948":30325,"63949":39531,"63950":40058,"63951":40477,"63952":28777,"63953":28778,"63954":40612,"63955":40830,"63956":40777,"63957":40856,"63958":30849,"63959":37561,"63960":35023,"63961":22715,"63962":24658,"63963":31911,"63964":23290,"63965":9556,"63966":9574,"63967":9559,"63968":9568,"63969":9580,"63970":9571,"63971":9562,"63972":9577,"63973":9565,"63974":9554,"63975":9572,"63976":9557,"63977":9566,"63978":9578,"63979":9569,"63980":9560,"63981":9575,"63982":9563,"63983":9555,"63984":9573,"63985":9558,"63986":9567,"63987":9579,"63988":9570,"63989":9561,"63990":9576,"63991":9564,"63992":9553,"63993":9552,"63994":9581,"63995":9582,"63996":9584,"63997":9583,"63998":9619,"64064":57344,"64065":57345,"64066":57346,"64067":57347,"64068":57348,"64069":57349,"64070":57350,"64071":57351,"64072":57352,"64073":57353,"64074":57354,"64075":57355,"64076":57356,"64077":57357,"64078":57358,"64079":57359,"64080":57360,"64081":57361,"64082":57362,"64083":57363,"64084":57364,"64085":57365,"64086":57366,"64087":57367,"64088":57368,"64089":57369,"64090":57370,"64091":57371,"64092":57372,"64093":57373,"64094":57374,"64095":57375,"64096":57376,"64097":57377,"64098":57378,"64099":57379,"64100":29234,"64101":29244,"64102":29286,"64103":29314,"64104":29327,"64105":29343,"64106":29357,"64107":29361,"64108":29368,"64109":29374,"64110":29389,"64111":29403,"64112":29476,"64113":29487,"64114":29496,"64115":29497,"64116":29629,"64117":29646,"64118":29681,"64119":29814,"64120":29858,"64121":29953,"64122":29977,"64123":29987,"64124":30012,"64125":30020,"64126":30025,"64161":30029,"64162":30061,"64163":30082,"64164":30083,"64165":30089,"64166":30124,"64167":30166,"64168":30185,"64169":30272,"64170":30285,"64171":30292,"64172":30312,"64173":30336,"64174":30339,"64175":30352,"64176":30391,"64177":30393,"64178":30477,"64179":30494,"64180":30531,"64181":30744,"64182":30748,"64183":30777,"64184":30780,"64185":30791,"64186":30806,"64187":30842,"64188":30901,"64189":30905,"64190":30918,"64191":30937,"64192":30983,"64193":31024,"64194":31028,"64195":31035,"64196":31104,"64197":31133,"64198":31171,"64199":31201,"64200":31238,"64201":31246,"64202":31299,"64203":31312,"64204":31427,"64205":31442,"64206":31458,"64207":31463,"64208":31480,"64209":31542,"64210":31586,"64211":31596,"64212":31610,"64213":31611,"64214":31642,"64215":31646,"64216":31647,"64217":31650,"64218":31655,"64219":31734,"64220":31762,"64221":31764,"64222":31823,"64223":31830,"64224":31832,"64225":31915,"64226":31994,"64227":32072,"64228":32075,"64229":32119,"64230":32212,"64231":32213,"64232":32214,"64233":32228,"64234":32333,"64235":32349,"64236":32383,"64237":32393,"64238":32398,"64239":32402,"64240":32468,"64241":32497,"64242":32530,"64243":32560,"64244":32625,"64245":32642,"64246":32686,"64247":32710,"64248":32800,"64249":32802,"64250":32805,"64251":32817,"64252":32863,"64253":32872,"64254":32940,"64320":32951,"64321":20890,"64322":21526,"64323":21524,"64324":13535,"64325":19581,"64326":25283,"64327":57508,"64328":57509,"64329":57510,"64330":21707,"64331":57512,"64332":21948,"64333":32950,"64334":20903,"64335":57516,"64336":57517,"64337":57518,"64338":21779,"64339":33318,"64340":57521,"64341":21790,"64342":21982,"64343":25529,"64344":26776,"64345":57526,"64346":21762,"64347":21865,"64348":30132,"64349":25596,"64350":40580,"64351":37418,"64352":57533,"64353":57534,"64354":57535,"64355":35015,"64356":24734,"64357":22053,"64358":28997,"64359":23282,"64360":57541,"64361":21135,"64362":22095,"64363":30611,"64364":34694,"64365":36397,"64366":33206,"64367":13822,"64368":29174,"64369":57550,"64370":34820,"64371":37765,"64372":57553,"64373":57554,"64374":30310,"64375":57556,"64376":40050,"64377":57558,"64378":25294,"64379":57560,"64380":40598,"64381":18825,"64382":31955,"64417":36570,"64418":40619,"64419":25831,"64420":57567,"64421":33450,"64422":26471,"64423":28018,"64424":30982,"64425":31172,"64426":32590,"64427":34798,"64428":57575,"64429":33726,"64430":34351,"64431":35237,"64432":17935,"64433":57580,"64434":39112,"64435":39232,"64436":39245,"64437":39436,"64438":39639,"64439":40600,"64440":40742,"64441":57588,"64442":20227,"64443":57590,"64444":20281,"64445":20274,"64446":20395,"64447":20566,"64448":57595,"64449":20526,"64450":20646,"64451":20697,"64452":20750,"64453":20717,"64454":20737,"64455":20980,"64456":21023,"64457":21088,"64458":21079,"64459":21146,"64460":21201,"64461":21216,"64462":21217,"64463":20947,"64464":20959,"64465":30022,"64466":20990,"64467":21298,"64468":21292,"64469":21299,"64470":21419,"64471":21418,"64472":40846,"64473":21609,"64474":21660,"64475":21466,"64476":27338,"64477":21875,"64478":57625,"64479":13782,"64480":57627,"64481":22033,"64482":22093,"64483":57630,"64484":22100,"64485":13811,"64486":57633,"64487":22342,"64488":22394,"64489":22375,"64490":22586,"64491":22502,"64492":22493,"64493":22592,"64494":57641,"64495":22566,"64496":22748,"64497":22967,"64498":23001,"64499":23584,"64500":57647,"64501":23761,"64502":23785,"64503":23878,"64504":23950,"64505":57652,"64506":24053,"64507":24075,"64508":24082,"64509":24110,"64510":24158,"64576":57658,"64577":24397,"64578":31357,"64579":23491,"64580":31419,"64581":57663,"64582":57664,"64583":24484,"64584":24506,"64585":24508,"64586":57668,"64587":24695,"64588":24740,"64589":24755,"64590":24829,"64591":24880,"64592":57674,"64593":24988,"64594":24921,"64595":24957,"64596":24924,"64597":25471,"64598":25058,"64599":28885,"64600":25145,"64601":25192,"64602":25221,"64603":25218,"64604":25254,"64605":25301,"64606":25444,"64607":25397,"64608":25744,"64609":14940,"64610":26184,"64611":26215,"64612":26398,"64613":26627,"64614":26540,"64615":26617,"64616":26806,"64617":26924,"64618":26881,"64619":26880,"64620":26826,"64621":26995,"64622":27008,"64623":26942,"64624":57706,"64625":27058,"64626":27072,"64627":27018,"64628":27130,"64629":27113,"64630":27314,"64631":27218,"64632":27293,"64633":27421,"64634":27474,"64635":27642,"64636":15569,"64637":27854,"64638":28239,"64673":28089,"64674":28484,"64675":57723,"64676":28634,"64677":28801,"64678":31180,"64679":28980,"64680":15820,"64681":29046,"64682":57730,"64683":57731,"64684":29205,"64685":29264,"64686":29319,"64687":29484,"64688":29362,"64689":29410,"64690":29442,"64691":29512,"64692":29480,"64693":29519,"64694":29553,"64695":25989,"64696":57744,"64697":29789,"64698":29800,"64699":29982,"64700":30035,"64701":30074,"64702":30369,"64703":30412,"64704":30500,"64705":30507,"64706":16485,"64707":30803,"64708":30931,"64709":30936,"64710":40318,"64711":30895,"64712":57760,"64713":24898,"64714":31145,"64715":39994,"64716":31188,"64717":57765,"64718":31277,"64719":31294,"64720":31305,"64721":31453,"64722":31450,"64723":30147,"64724":30215,"64725":30210,"64726":57774,"64727":30311,"64728":30319,"64729":22048,"64730":35431,"64731":40727,"64732":31519,"64733":31634,"64734":31651,"64735":31695,"64736":57784,"64737":31740,"64738":31810,"64739":31825,"64740":31837,"64741":31856,"64742":31870,"64743":31878,"64744":31875,"64745":31916,"64746":31943,"64747":31938,"64748":57796,"64749":31962,"64750":57798,"64751":32077,"64752":32090,"64753":32245,"64754":32295,"64755":32366,"64756":40597,"64757":21107,"64758":32797,"64759":32866,"64760":32867,"64761":32870,"64762":32859,"64763":32934,"64764":33027,"64765":40577,"64766":33224,"64832":57815,"64833":36768,"64834":33270,"64835":33306,"64836":57819,"64837":34673,"64838":34729,"64839":34700,"64840":40606,"64841":34753,"64842":40476,"64843":57826,"64844":34774,"64845":34805,"64846":34831,"64847":34840,"64848":34861,"64849":34882,"64850":34885,"64851":39989,"64852":34926,"64853":34986,"64854":34976,"64855":25245,"64856":35139,"64857":35149,"64858":29042,"64859":34910,"64860":57843,"64861":33533,"64862":17591,"64863":33488,"64864":33669,"64865":40194,"64866":40809,"64867":33824,"64868":57851,"64869":34010,"64870":33965,"64871":17659,"64872":34123,"64873":57856,"64874":34306,"64875":34320,"64876":25553,"64877":35209,"64878":35210,"64879":35220,"64880":40005,"64881":35260,"64882":35454,"64883":35401,"64884":35596,"64885":35651,"64886":35713,"64887":35660,"64888":57871,"64889":36013,"64890":36075,"64891":36087,"64892":36108,"64893":36226,"64894":36262,"64929":36308,"64930":36392,"64931":36431,"64932":36471,"64933":36469,"64934":36519,"64935":36633,"64936":57885,"64937":36700,"64938":40260,"64939":37060,"64940":37201,"64941":57890,"64942":37212,"64943":37209,"64944":37223,"64945":37244,"64946":37262,"64947":37307,"64948":40616,"64949":36950,"64950":36940,"64951":37374,"64952":37474,"64953":37566,"64954":37739,"64955":37742,"64956":37818,"64957":37927,"64958":38295,"64959":38311,"64960":57909,"64961":38456,"64962":57911,"64963":38531,"64964":38550,"64965":38529,"64966":38589,"64967":38659,"64968":38689,"64969":38705,"64970":38751,"64971":38815,"64972":38836,"64973":38840,"64974":38842,"64975":38846,"64976":38856,"64977":40639,"64978":38943,"64979":38958,"64980":40869,"64981":38983,"64982":38987,"64983":39014,"64984":39020,"64985":39092,"64986":40794,"64987":39132,"64988":39142,"64989":39234,"64990":39225,"64991":39227,"64992":40787,"64993":39242,"64994":40773,"64995":19326,"64996":39386,"64997":31432,"64998":39610,"64999":39613,"65000":40706,"65001":39722,"65002":57951,"65003":39725,"65004":39650,"65005":39682,"65006":39679,"65007":19463,"65008":39689,"65009":19460,"65010":19515,"65011":39823,"65012":39837,"65013":39856,"65014":39948,"65015":39957,"65016":39946,"65017":39935,"65018":39982,"65019":33000,"65020":33001,"65021":33004,"65022":33038,"65088":27705,"65089":20074,"65090":38465,"65091":22770,"65092":31074,"65093":26658,"65094":57978,"65095":57979,"65096":33031,"65097":22487,"65098":17642,"65099":25653,"65100":34100,"65101":16607,"65102":57986,"65103":26906,"65104":39938,"65105":30129,"65106":33747,"65107":29041,"65108":27147,"65109":57993,"65110":27258,"65111":39668,"65112":57996,"65113":57997,"65114":30649,"65115":25904,"65116":28054,"65117":22071,"65118":26405,"65119":27179,"65120":32093,"65121":36961,"65122":20120,"65123":31910,"65124":31545,"65125":58009,"65126":22901,"65127":14023,"65128":28799,"65129":58013,"65130":28299,"65131":58015,"65132":58016,"65133":38749,"65134":37584,"65135":22356,"65136":58020,"65137":16089,"65138":58022,"65139":58023,"65140":24985,"65141":29792,"65142":28991,"65143":31022,"65144":23190,"65145":37704,"65146":26254,"65147":20477,"65148":37697,"65149":13908,"65150":23925,"65185":28702,"65186":25979,"65187":28813,"65188":24269,"65189":58039,"65190":24743,"65191":31408,"65192":24419,"65193":58043,"65194":29687,"65195":58045,"65196":29800,"65197":30132,"65198":58048,"65199":39785,"65200":189,"65201":8531,"65202":8532,"65203":188,"65204":190,"65205":8533,"65206":8534,"65207":8535,"65208":8536,"65209":8537,"65210":8538,"65211":34450,"65212":34464,"65213":34477,"65214":34482,"65215":34725,"65216":34737,"65217":8539,"65218":8540,"65219":8541,"65220":8542,"65221":34778,"65222":34895,"65223":34912,"65224":34951,"65225":34959,"65226":34960,"65227":35046,"65228":35071,"65229":35072,"65230":35108,"65231":35143,"65232":35156,"65233":35173,"65234":35200,"65235":35217,"65236":35356,"65237":35369,"65238":35371,"65239":35384,"65240":35389,"65241":8978,"65242":35472,"65243":35476,"65244":35484,"65245":35497,"65246":35503,"65247":35508,"65248":35562,"65249":35615,"65250":8240,"65251":35647,"65252":35661,"65253":35678,"65254":35682,"65255":35689,"65256":35739,"65257":35921,"65258":35995,"65259":35999,"65260":36052,"65261":36054,"65262":33042,"65263":33073,"65264":33078,"65265":33119,"65266":33133,"65267":33149,"65268":33171,"65269":33194,"65270":33208,"65271":33217,"65272":33321,"65273":33325,"65274":33326,"65275":33342,"65276":33378,"65277":33386,"65278":33416,"NaN":null} \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/gbk.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/gbk.js deleted file mode 100644 index c464623e..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/encodings/table/gbk.js +++ /dev/null @@ -1 +0,0 @@ -module.exports={33088:19970,33089:19972,33090:19973,33091:19974,33092:19983,33093:19986,33094:19991,33095:19999,33096:20000,33097:20001,33098:20003,33099:20006,33100:20009,33101:20014,33102:20015,33103:20017,33104:20019,33105:20021,33106:20023,33107:20028,33108:20032,33109:20033,33110:20034,33111:20036,33112:20038,33113:20042,33114:20049,33115:20053,33116:20055,33117:20058,33118:20059,33119:20066,33120:20067,33121:20068,33122:20069,33123:20071,33124:20072,33125:20074,33126:20075,33127:20076,33128:20077,33129:20078,33130:20079,33131:20082,33132:20084,33133:20085,33134:20086,33135:20087,33136:20088,33137:20089,33138:20090,33139:20091,33140:20092,33141:20093,33142:20095,33143:20096,33144:20097,33145:20098,33146:20099,33147:20100,33148:20101,33149:20103,33150:20106,33152:20112,33153:20118,33154:20119,33155:20121,33156:20124,33157:20125,33158:20126,33159:20131,33160:20138,33161:20143,33162:20144,33163:20145,33164:20148,33165:20150,33166:20151,33167:20152,33168:20153,33169:20156,33170:20157,33171:20158,33172:20168,33173:20172,33174:20175,33175:20176,33176:20178,33177:20186,33178:20187,33179:20188,33180:20192,33181:20194,33182:20198,33183:20199,33184:20201,33185:20205,33186:20206,33187:20207,33188:20209,33189:20212,33190:20216,33191:20217,33192:20218,33193:20220,33194:20222,33195:20224,33196:20226,33197:20227,33198:20228,33199:20229,33200:20230,33201:20231,33202:20232,33203:20235,33204:20236,33205:20242,33206:20243,33207:20244,33208:20245,33209:20246,33210:20252,33211:20253,33212:20257,33213:20259,33214:20264,33215:20265,33216:20268,33217:20269,33218:20270,33219:20273,33220:20275,33221:20277,33222:20279,33223:20281,33224:20283,33225:20286,33226:20287,33227:20288,33228:20289,33229:20290,33230:20292,33231:20293,33232:20295,33233:20296,33234:20297,33235:20298,33236:20299,33237:20300,33238:20306,33239:20308,33240:20310,33241:20321,33242:20322,33243:20326,33244:20328,33245:20330,33246:20331,33247:20333,33248:20334,33249:20337,33250:20338,33251:20341,33252:20343,33253:20344,33254:20345,33255:20346,33256:20349,33257:20352,33258:20353,33259:20354,33260:20357,33261:20358,33262:20359,33263:20362,33264:20364,33265:20366,33266:20368,33267:20370,33268:20371,33269:20373,33270:20374,33271:20376,33272:20377,33273:20378,33274:20380,33275:20382,33276:20383,33277:20385,33278:20386,33344:20388,33345:20395,33346:20397,33347:20400,33348:20401,33349:20402,33350:20403,33351:20404,33352:20406,33353:20407,33354:20408,33355:20409,33356:20410,33357:20411,33358:20412,33359:20413,33360:20414,33361:20416,33362:20417,33363:20418,33364:20422,33365:20423,33366:20424,33367:20425,33368:20427,33369:20428,33370:20429,33371:20434,33372:20435,33373:20436,33374:20437,33375:20438,33376:20441,33377:20443,33378:20448,33379:20450,33380:20452,33381:20453,33382:20455,33383:20459,33384:20460,33385:20464,33386:20466,33387:20468,33388:20469,33389:20470,33390:20471,33391:20473,33392:20475,33393:20476,33394:20477,33395:20479,33396:20480,33397:20481,33398:20482,33399:20483,33400:20484,33401:20485,33402:20486,33403:20487,33404:20488,33405:20489,33406:20490,33408:20491,33409:20494,33410:20496,33411:20497,33412:20499,33413:20501,33414:20502,33415:20503,33416:20507,33417:20509,33418:20510,33419:20512,33420:20514,33421:20515,33422:20516,33423:20519,33424:20523,33425:20527,33426:20528,33427:20529,33428:20530,33429:20531,33430:20532,33431:20533,33432:20534,33433:20535,33434:20536,33435:20537,33436:20539,33437:20541,33438:20543,33439:20544,33440:20545,33441:20546,33442:20548,33443:20549,33444:20550,33445:20553,33446:20554,33447:20555,33448:20557,33449:20560,33450:20561,33451:20562,33452:20563,33453:20564,33454:20566,33455:20567,33456:20568,33457:20569,33458:20571,33459:20573,33460:20574,33461:20575,33462:20576,33463:20577,33464:20578,33465:20579,33466:20580,33467:20582,33468:20583,33469:20584,33470:20585,33471:20586,33472:20587,33473:20589,33474:20590,33475:20591,33476:20592,33477:20593,33478:20594,33479:20595,33480:20596,33481:20597,33482:20600,33483:20601,33484:20602,33485:20604,33486:20605,33487:20609,33488:20610,33489:20611,33490:20612,33491:20614,33492:20615,33493:20617,33494:20618,33495:20619,33496:20620,33497:20622,33498:20623,33499:20624,33500:20625,33501:20626,33502:20627,33503:20628,33504:20629,33505:20630,33506:20631,33507:20632,33508:20633,33509:20634,33510:20635,33511:20636,33512:20637,33513:20638,33514:20639,33515:20640,33516:20641,33517:20642,33518:20644,33519:20646,33520:20650,33521:20651,33522:20653,33523:20654,33524:20655,33525:20656,33526:20657,33527:20659,33528:20660,33529:20661,33530:20662,33531:20663,33532:20664,33533:20665,33534:20668,33600:20669,33601:20670,33602:20671,33603:20672,33604:20673,33605:20674,33606:20675,33607:20676,33608:20677,33609:20678,33610:20679,33611:20680,33612:20681,33613:20682,33614:20683,33615:20684,33616:20685,33617:20686,33618:20688,33619:20689,33620:20690,33621:20691,33622:20692,33623:20693,33624:20695,33625:20696,33626:20697,33627:20699,33628:20700,33629:20701,33630:20702,33631:20703,33632:20704,33633:20705,33634:20706,33635:20707,33636:20708,33637:20709,33638:20712,33639:20713,33640:20714,33641:20715,33642:20719,33643:20720,33644:20721,33645:20722,33646:20724,33647:20726,33648:20727,33649:20728,33650:20729,33651:20730,33652:20732,33653:20733,33654:20734,33655:20735,33656:20736,33657:20737,33658:20738,33659:20739,33660:20740,33661:20741,33662:20744,33664:20745,33665:20746,33666:20748,33667:20749,33668:20750,33669:20751,33670:20752,33671:20753,33672:20755,33673:20756,33674:20757,33675:20758,33676:20759,33677:20760,33678:20761,33679:20762,33680:20763,33681:20764,33682:20765,33683:20766,33684:20767,33685:20768,33686:20770,33687:20771,33688:20772,33689:20773,33690:20774,33691:20775,33692:20776,33693:20777,33694:20778,33695:20779,33696:20780,33697:20781,33698:20782,33699:20783,33700:20784,33701:20785,33702:20786,33703:20787,33704:20788,33705:20789,33706:20790,33707:20791,33708:20792,33709:20793,33710:20794,33711:20795,33712:20796,33713:20797,33714:20798,33715:20802,33716:20807,33717:20810,33718:20812,33719:20814,33720:20815,33721:20816,33722:20818,33723:20819,33724:20823,33725:20824,33726:20825,33727:20827,33728:20829,33729:20830,33730:20831,33731:20832,33732:20833,33733:20835,33734:20836,33735:20838,33736:20839,33737:20841,33738:20842,33739:20847,33740:20850,33741:20858,33742:20862,33743:20863,33744:20867,33745:20868,33746:20870,33747:20871,33748:20874,33749:20875,33750:20878,33751:20879,33752:20880,33753:20881,33754:20883,33755:20884,33756:20888,33757:20890,33758:20893,33759:20894,33760:20895,33761:20897,33762:20899,33763:20902,33764:20903,33765:20904,33766:20905,33767:20906,33768:20909,33769:20910,33770:20916,33771:20920,33772:20921,33773:20922,33774:20926,33775:20927,33776:20929,33777:20930,33778:20931,33779:20933,33780:20936,33781:20938,33782:20941,33783:20942,33784:20944,33785:20946,33786:20947,33787:20948,33788:20949,33789:20950,33790:20951,33856:20952,33857:20953,33858:20954,33859:20956,33860:20958,33861:20959,33862:20962,33863:20963,33864:20965,33865:20966,33866:20967,33867:20968,33868:20969,33869:20970,33870:20972,33871:20974,33872:20977,33873:20978,33874:20980,33875:20983,33876:20990,33877:20996,33878:20997,33879:21001,33880:21003,33881:21004,33882:21007,33883:21008,33884:21011,33885:21012,33886:21013,33887:21020,33888:21022,33889:21023,33890:21025,33891:21026,33892:21027,33893:21029,33894:21030,33895:21031,33896:21034,33897:21036,33898:21039,33899:21041,33900:21042,33901:21044,33902:21045,33903:21052,33904:21054,33905:21060,33906:21061,33907:21062,33908:21063,33909:21064,33910:21065,33911:21067,33912:21070,33913:21071,33914:21074,33915:21075,33916:21077,33917:21079,33918:21080,33920:21081,33921:21082,33922:21083,33923:21085,33924:21087,33925:21088,33926:21090,33927:21091,33928:21092,33929:21094,33930:21096,33931:21099,33932:21100,33933:21101,33934:21102,33935:21104,33936:21105,33937:21107,33938:21108,33939:21109,33940:21110,33941:21111,33942:21112,33943:21113,33944:21114,33945:21115,33946:21116,33947:21118,33948:21120,33949:21123,33950:21124,33951:21125,33952:21126,33953:21127,33954:21129,33955:21130,33956:21131,33957:21132,33958:21133,33959:21134,33960:21135,33961:21137,33962:21138,33963:21140,33964:21141,33965:21142,33966:21143,33967:21144,33968:21145,33969:21146,33970:21148,33971:21156,33972:21157,33973:21158,33974:21159,33975:21166,33976:21167,33977:21168,33978:21172,33979:21173,33980:21174,33981:21175,33982:21176,33983:21177,33984:21178,33985:21179,33986:21180,33987:21181,33988:21184,33989:21185,33990:21186,33991:21188,33992:21189,33993:21190,33994:21192,33995:21194,33996:21196,33997:21197,33998:21198,33999:21199,34000:21201,34001:21203,34002:21204,34003:21205,34004:21207,34005:21209,34006:21210,34007:21211,34008:21212,34009:21213,34010:21214,34011:21216,34012:21217,34013:21218,34014:21219,34015:21221,34016:21222,34017:21223,34018:21224,34019:21225,34020:21226,34021:21227,34022:21228,34023:21229,34024:21230,34025:21231,34026:21233,34027:21234,34028:21235,34029:21236,34030:21237,34031:21238,34032:21239,34033:21240,34034:21243,34035:21244,34036:21245,34037:21249,34038:21250,34039:21251,34040:21252,34041:21255,34042:21257,34043:21258,34044:21259,34045:21260,34046:21262,34112:21265,34113:21266,34114:21267,34115:21268,34116:21272,34117:21275,34118:21276,34119:21278,34120:21279,34121:21282,34122:21284,34123:21285,34124:21287,34125:21288,34126:21289,34127:21291,34128:21292,34129:21293,34130:21295,34131:21296,34132:21297,34133:21298,34134:21299,34135:21300,34136:21301,34137:21302,34138:21303,34139:21304,34140:21308,34141:21309,34142:21312,34143:21314,34144:21316,34145:21318,34146:21323,34147:21324,34148:21325,34149:21328,34150:21332,34151:21336,34152:21337,34153:21339,34154:21341,34155:21349,34156:21352,34157:21354,34158:21356,34159:21357,34160:21362,34161:21366,34162:21369,34163:21371,34164:21372,34165:21373,34166:21374,34167:21376,34168:21377,34169:21379,34170:21383,34171:21384,34172:21386,34173:21390,34174:21391,34176:21392,34177:21393,34178:21394,34179:21395,34180:21396,34181:21398,34182:21399,34183:21401,34184:21403,34185:21404,34186:21406,34187:21408,34188:21409,34189:21412,34190:21415,34191:21418,34192:21419,34193:21420,34194:21421,34195:21423,34196:21424,34197:21425,34198:21426,34199:21427,34200:21428,34201:21429,34202:21431,34203:21432,34204:21433,34205:21434,34206:21436,34207:21437,34208:21438,34209:21440,34210:21443,34211:21444,34212:21445,34213:21446,34214:21447,34215:21454,34216:21455,34217:21456,34218:21458,34219:21459,34220:21461,34221:21466,34222:21468,34223:21469,34224:21470,34225:21473,34226:21474,34227:21479,34228:21492,34229:21498,34230:21502,34231:21503,34232:21504,34233:21506,34234:21509,34235:21511,34236:21515,34237:21524,34238:21528,34239:21529,34240:21530,34241:21532,34242:21538,34243:21540,34244:21541,34245:21546,34246:21552,34247:21555,34248:21558,34249:21559,34250:21562,34251:21565,34252:21567,34253:21569,34254:21570,34255:21572,34256:21573,34257:21575,34258:21577,34259:21580,34260:21581,34261:21582,34262:21583,34263:21585,34264:21594,34265:21597,34266:21598,34267:21599,34268:21600,34269:21601,34270:21603,34271:21605,34272:21607,34273:21609,34274:21610,34275:21611,34276:21612,34277:21613,34278:21614,34279:21615,34280:21616,34281:21620,34282:21625,34283:21626,34284:21630,34285:21631,34286:21633,34287:21635,34288:21637,34289:21639,34290:21640,34291:21641,34292:21642,34293:21645,34294:21649,34295:21651,34296:21655,34297:21656,34298:21660,34299:21662,34300:21663,34301:21664,34302:21665,34368:21666,34369:21669,34370:21678,34371:21680,34372:21682,34373:21685,34374:21686,34375:21687,34376:21689,34377:21690,34378:21692,34379:21694,34380:21699,34381:21701,34382:21706,34383:21707,34384:21718,34385:21720,34386:21723,34387:21728,34388:21729,34389:21730,34390:21731,34391:21732,34392:21739,34393:21740,34394:21743,34395:21744,34396:21745,34397:21748,34398:21749,34399:21750,34400:21751,34401:21752,34402:21753,34403:21755,34404:21758,34405:21760,34406:21762,34407:21763,34408:21764,34409:21765,34410:21768,34411:21770,34412:21771,34413:21772,34414:21773,34415:21774,34416:21778,34417:21779,34418:21781,34419:21782,34420:21783,34421:21784,34422:21785,34423:21786,34424:21788,34425:21789,34426:21790,34427:21791,34428:21793,34429:21797,34430:21798,34432:21800,34433:21801,34434:21803,34435:21805,34436:21810,34437:21812,34438:21813,34439:21814,34440:21816,34441:21817,34442:21818,34443:21819,34444:21821,34445:21824,34446:21826,34447:21829,34448:21831,34449:21832,34450:21835,34451:21836,34452:21837,34453:21838,34454:21839,34455:21841,34456:21842,34457:21843,34458:21844,34459:21847,34460:21848,34461:21849,34462:21850,34463:21851,34464:21853,34465:21854,34466:21855,34467:21856,34468:21858,34469:21859,34470:21864,34471:21865,34472:21867,34473:21871,34474:21872,34475:21873,34476:21874,34477:21875,34478:21876,34479:21881,34480:21882,34481:21885,34482:21887,34483:21893,34484:21894,34485:21900,34486:21901,34487:21902,34488:21904,34489:21906,34490:21907,34491:21909,34492:21910,34493:21911,34494:21914,34495:21915,34496:21918,34497:21920,34498:21921,34499:21922,34500:21923,34501:21924,34502:21925,34503:21926,34504:21928,34505:21929,34506:21930,34507:21931,34508:21932,34509:21933,34510:21934,34511:21935,34512:21936,34513:21938,34514:21940,34515:21942,34516:21944,34517:21946,34518:21948,34519:21951,34520:21952,34521:21953,34522:21954,34523:21955,34524:21958,34525:21959,34526:21960,34527:21962,34528:21963,34529:21966,34530:21967,34531:21968,34532:21973,34533:21975,34534:21976,34535:21977,34536:21978,34537:21979,34538:21982,34539:21984,34540:21986,34541:21991,34542:21993,34543:21997,34544:21998,34545:22000,34546:22001,34547:22004,34548:22006,34549:22008,34550:22009,34551:22010,34552:22011,34553:22012,34554:22015,34555:22018,34556:22019,34557:22020,34558:22021,34624:22022,34625:22023,34626:22026,34627:22027,34628:22029,34629:22032,34630:22033,34631:22034,34632:22035,34633:22036,34634:22037,34635:22038,34636:22039,34637:22041,34638:22042,34639:22044,34640:22045,34641:22048,34642:22049,34643:22050,34644:22053,34645:22054,34646:22056,34647:22057,34648:22058,34649:22059,34650:22062,34651:22063,34652:22064,34653:22067,34654:22069,34655:22071,34656:22072,34657:22074,34658:22076,34659:22077,34660:22078,34661:22080,34662:22081,34663:22082,34664:22083,34665:22084,34666:22085,34667:22086,34668:22087,34669:22088,34670:22089,34671:22090,34672:22091,34673:22095,34674:22096,34675:22097,34676:22098,34677:22099,34678:22101,34679:22102,34680:22106,34681:22107,34682:22109,34683:22110,34684:22111,34685:22112,34686:22113,34688:22115,34689:22117,34690:22118,34691:22119,34692:22125,34693:22126,34694:22127,34695:22128,34696:22130,34697:22131,34698:22132,34699:22133,34700:22135,34701:22136,34702:22137,34703:22138,34704:22141,34705:22142,34706:22143,34707:22144,34708:22145,34709:22146,34710:22147,34711:22148,34712:22151,34713:22152,34714:22153,34715:22154,34716:22155,34717:22156,34718:22157,34719:22160,34720:22161,34721:22162,34722:22164,34723:22165,34724:22166,34725:22167,34726:22168,34727:22169,34728:22170,34729:22171,34730:22172,34731:22173,34732:22174,34733:22175,34734:22176,34735:22177,34736:22178,34737:22180,34738:22181,34739:22182,34740:22183,34741:22184,34742:22185,34743:22186,34744:22187,34745:22188,34746:22189,34747:22190,34748:22192,34749:22193,34750:22194,34751:22195,34752:22196,34753:22197,34754:22198,34755:22200,34756:22201,34757:22202,34758:22203,34759:22205,34760:22206,34761:22207,34762:22208,34763:22209,34764:22210,34765:22211,34766:22212,34767:22213,34768:22214,34769:22215,34770:22216,34771:22217,34772:22219,34773:22220,34774:22221,34775:22222,34776:22223,34777:22224,34778:22225,34779:22226,34780:22227,34781:22229,34782:22230,34783:22232,34784:22233,34785:22236,34786:22243,34787:22245,34788:22246,34789:22247,34790:22248,34791:22249,34792:22250,34793:22252,34794:22254,34795:22255,34796:22258,34797:22259,34798:22262,34799:22263,34800:22264,34801:22267,34802:22268,34803:22272,34804:22273,34805:22274,34806:22277,34807:22279,34808:22283,34809:22284,34810:22285,34811:22286,34812:22287,34813:22288,34814:22289,34880:22290,34881:22291,34882:22292,34883:22293,34884:22294,34885:22295,34886:22296,34887:22297,34888:22298,34889:22299,34890:22301,34891:22302,34892:22304,34893:22305,34894:22306,34895:22308,34896:22309,34897:22310,34898:22311,34899:22315,34900:22321,34901:22322,34902:22324,34903:22325,34904:22326,34905:22327,34906:22328,34907:22332,34908:22333,34909:22335,34910:22337,34911:22339,34912:22340,34913:22341,34914:22342,34915:22344,34916:22345,34917:22347,34918:22354,34919:22355,34920:22356,34921:22357,34922:22358,34923:22360,34924:22361,34925:22370,34926:22371,34927:22373,34928:22375,34929:22380,34930:22382,34931:22384,34932:22385,34933:22386,34934:22388,34935:22389,34936:22392,34937:22393,34938:22394,34939:22397,34940:22398,34941:22399,34942:22400,34944:22401,34945:22407,34946:22408,34947:22409,34948:22410,34949:22413,34950:22414,34951:22415,34952:22416,34953:22417,34954:22420,34955:22421,34956:22422,34957:22423,34958:22424,34959:22425,34960:22426,34961:22428,34962:22429,34963:22430,34964:22431,34965:22437,34966:22440,34967:22442,34968:22444,34969:22447,34970:22448,34971:22449,34972:22451,34973:22453,34974:22454,34975:22455,34976:22457,34977:22458,34978:22459,34979:22460,34980:22461,34981:22462,34982:22463,34983:22464,34984:22465,34985:22468,34986:22469,34987:22470,34988:22471,34989:22472,34990:22473,34991:22474,34992:22476,34993:22477,34994:22480,34995:22481,34996:22483,34997:22486,34998:22487,34999:22491,35000:22492,35001:22494,35002:22497,35003:22498,35004:22499,35005:22501,35006:22502,35007:22503,35008:22504,35009:22505,35010:22506,35011:22507,35012:22508,35013:22510,35014:22512,35015:22513,35016:22514,35017:22515,35018:22517,35019:22518,35020:22519,35021:22523,35022:22524,35023:22526,35024:22527,35025:22529,35026:22531,35027:22532,35028:22533,35029:22536,35030:22537,35031:22538,35032:22540,35033:22542,35034:22543,35035:22544,35036:22546,35037:22547,35038:22548,35039:22550,35040:22551,35041:22552,35042:22554,35043:22555,35044:22556,35045:22557,35046:22559,35047:22562,35048:22563,35049:22565,35050:22566,35051:22567,35052:22568,35053:22569,35054:22571,35055:22572,35056:22573,35057:22574,35058:22575,35059:22577,35060:22578,35061:22579,35062:22580,35063:22582,35064:22583,35065:22584,35066:22585,35067:22586,35068:22587,35069:22588,35070:22589,35136:22590,35137:22591,35138:22592,35139:22593,35140:22594,35141:22595,35142:22597,35143:22598,35144:22599,35145:22600,35146:22601,35147:22602,35148:22603,35149:22606,35150:22607,35151:22608,35152:22610,35153:22611,35154:22613,35155:22614,35156:22615,35157:22617,35158:22618,35159:22619,35160:22620,35161:22621,35162:22623,35163:22624,35164:22625,35165:22626,35166:22627,35167:22628,35168:22630,35169:22631,35170:22632,35171:22633,35172:22634,35173:22637,35174:22638,35175:22639,35176:22640,35177:22641,35178:22642,35179:22643,35180:22644,35181:22645,35182:22646,35183:22647,35184:22648,35185:22649,35186:22650,35187:22651,35188:22652,35189:22653,35190:22655,35191:22658,35192:22660,35193:22662,35194:22663,35195:22664,35196:22666,35197:22667,35198:22668,35200:22669,35201:22670,35202:22671,35203:22672,35204:22673,35205:22676,35206:22677,35207:22678,35208:22679,35209:22680,35210:22683,35211:22684,35212:22685,35213:22688,35214:22689,35215:22690,35216:22691,35217:22692,35218:22693,35219:22694,35220:22695,35221:22698,35222:22699,35223:22700,35224:22701,35225:22702,35226:22703,35227:22704,35228:22705,35229:22706,35230:22707,35231:22708,35232:22709,35233:22710,35234:22711,35235:22712,35236:22713,35237:22714,35238:22715,35239:22717,35240:22718,35241:22719,35242:22720,35243:22722,35244:22723,35245:22724,35246:22726,35247:22727,35248:22728,35249:22729,35250:22730,35251:22731,35252:22732,35253:22733,35254:22734,35255:22735,35256:22736,35257:22738,35258:22739,35259:22740,35260:22742,35261:22743,35262:22744,35263:22745,35264:22746,35265:22747,35266:22748,35267:22749,35268:22750,35269:22751,35270:22752,35271:22753,35272:22754,35273:22755,35274:22757,35275:22758,35276:22759,35277:22760,35278:22761,35279:22762,35280:22765,35281:22767,35282:22769,35283:22770,35284:22772,35285:22773,35286:22775,35287:22776,35288:22778,35289:22779,35290:22780,35291:22781,35292:22782,35293:22783,35294:22784,35295:22785,35296:22787,35297:22789,35298:22790,35299:22792,35300:22793,35301:22794,35302:22795,35303:22796,35304:22798,35305:22800,35306:22801,35307:22802,35308:22803,35309:22807,35310:22808,35311:22811,35312:22813,35313:22814,35314:22816,35315:22817,35316:22818,35317:22819,35318:22822,35319:22824,35320:22828,35321:22832,35322:22834,35323:22835,35324:22837,35325:22838,35326:22843,35392:22845,35393:22846,35394:22847,35395:22848,35396:22851,35397:22853,35398:22854,35399:22858,35400:22860,35401:22861,35402:22864,35403:22866,35404:22867,35405:22873,35406:22875,35407:22876,35408:22877,35409:22878,35410:22879,35411:22881,35412:22883,35413:22884,35414:22886,35415:22887,35416:22888,35417:22889,35418:22890,35419:22891,35420:22892,35421:22893,35422:22894,35423:22895,35424:22896,35425:22897,35426:22898,35427:22901,35428:22903,35429:22906,35430:22907,35431:22908,35432:22910,35433:22911,35434:22912,35435:22917,35436:22921,35437:22923,35438:22924,35439:22926,35440:22927,35441:22928,35442:22929,35443:22932,35444:22933,35445:22936,35446:22938,35447:22939,35448:22940,35449:22941,35450:22943,35451:22944,35452:22945,35453:22946,35454:22950,35456:22951,35457:22956,35458:22957,35459:22960,35460:22961,35461:22963,35462:22964,35463:22965,35464:22966,35465:22967,35466:22968,35467:22970,35468:22972,35469:22973,35470:22975,35471:22976,35472:22977,35473:22978,35474:22979,35475:22980,35476:22981,35477:22983,35478:22984,35479:22985,35480:22988,35481:22989,35482:22990,35483:22991,35484:22997,35485:22998,35486:23001,35487:23003,35488:23006,35489:23007,35490:23008,35491:23009,35492:23010,35493:23012,35494:23014,35495:23015,35496:23017,35497:23018,35498:23019,35499:23021,35500:23022,35501:23023,35502:23024,35503:23025,35504:23026,35505:23027,35506:23028,35507:23029,35508:23030,35509:23031,35510:23032,35511:23034,35512:23036,35513:23037,35514:23038,35515:23040,35516:23042,35517:23050,35518:23051,35519:23053,35520:23054,35521:23055,35522:23056,35523:23058,35524:23060,35525:23061,35526:23062,35527:23063,35528:23065,35529:23066,35530:23067,35531:23069,35532:23070,35533:23073,35534:23074,35535:23076,35536:23078,35537:23079,35538:23080,35539:23082,35540:23083,35541:23084,35542:23085,35543:23086,35544:23087,35545:23088,35546:23091,35547:23093,35548:23095,35549:23096,35550:23097,35551:23098,35552:23099,35553:23101,35554:23102,35555:23103,35556:23105,35557:23106,35558:23107,35559:23108,35560:23109,35561:23111,35562:23112,35563:23115,35564:23116,35565:23117,35566:23118,35567:23119,35568:23120,35569:23121,35570:23122,35571:23123,35572:23124,35573:23126,35574:23127,35575:23128,35576:23129,35577:23131,35578:23132,35579:23133,35580:23134,35581:23135,35582:23136,35648:23137,35649:23139,35650:23140,35651:23141,35652:23142,35653:23144,35654:23145,35655:23147,35656:23148,35657:23149,35658:23150,35659:23151,35660:23152,35661:23153,35662:23154,35663:23155,35664:23160,35665:23161,35666:23163,35667:23164,35668:23165,35669:23166,35670:23168,35671:23169,35672:23170,35673:23171,35674:23172,35675:23173,35676:23174,35677:23175,35678:23176,35679:23177,35680:23178,35681:23179,35682:23180,35683:23181,35684:23182,35685:23183,35686:23184,35687:23185,35688:23187,35689:23188,35690:23189,35691:23190,35692:23191,35693:23192,35694:23193,35695:23196,35696:23197,35697:23198,35698:23199,35699:23200,35700:23201,35701:23202,35702:23203,35703:23204,35704:23205,35705:23206,35706:23207,35707:23208,35708:23209,35709:23211,35710:23212,35712:23213,35713:23214,35714:23215,35715:23216,35716:23217,35717:23220,35718:23222,35719:23223,35720:23225,35721:23226,35722:23227,35723:23228,35724:23229,35725:23231,35726:23232,35727:23235,35728:23236,35729:23237,35730:23238,35731:23239,35732:23240,35733:23242,35734:23243,35735:23245,35736:23246,35737:23247,35738:23248,35739:23249,35740:23251,35741:23253,35742:23255,35743:23257,35744:23258,35745:23259,35746:23261,35747:23262,35748:23263,35749:23266,35750:23268,35751:23269,35752:23271,35753:23272,35754:23274,35755:23276,35756:23277,35757:23278,35758:23279,35759:23280,35760:23282,35761:23283,35762:23284,35763:23285,35764:23286,35765:23287,35766:23288,35767:23289,35768:23290,35769:23291,35770:23292,35771:23293,35772:23294,35773:23295,35774:23296,35775:23297,35776:23298,35777:23299,35778:23300,35779:23301,35780:23302,35781:23303,35782:23304,35783:23306,35784:23307,35785:23308,35786:23309,35787:23310,35788:23311,35789:23312,35790:23313,35791:23314,35792:23315,35793:23316,35794:23317,35795:23320,35796:23321,35797:23322,35798:23323,35799:23324,35800:23325,35801:23326,35802:23327,35803:23328,35804:23329,35805:23330,35806:23331,35807:23332,35808:23333,35809:23334,35810:23335,35811:23336,35812:23337,35813:23338,35814:23339,35815:23340,35816:23341,35817:23342,35818:23343,35819:23344,35820:23345,35821:23347,35822:23349,35823:23350,35824:23352,35825:23353,35826:23354,35827:23355,35828:23356,35829:23357,35830:23358,35831:23359,35832:23361,35833:23362,35834:23363,35835:23364,35836:23365,35837:23366,35838:23367,35904:23368,35905:23369,35906:23370,35907:23371,35908:23372,35909:23373,35910:23374,35911:23375,35912:23378,35913:23382,35914:23390,35915:23392,35916:23393,35917:23399,35918:23400,35919:23403,35920:23405,35921:23406,35922:23407,35923:23410,35924:23412,35925:23414,35926:23415,35927:23416,35928:23417,35929:23419,35930:23420,35931:23422,35932:23423,35933:23426,35934:23430,35935:23434,35936:23437,35937:23438,35938:23440,35939:23441,35940:23442,35941:23444,35942:23446,35943:23455,35944:23463,35945:23464,35946:23465,35947:23468,35948:23469,35949:23470,35950:23471,35951:23473,35952:23474,35953:23479,35954:23482,35955:23483,35956:23484,35957:23488,35958:23489,35959:23491,35960:23496,35961:23497,35962:23498,35963:23499,35964:23501,35965:23502,35966:23503,35968:23505,35969:23508,35970:23509,35971:23510,35972:23511,35973:23512,35974:23513,35975:23514,35976:23515,35977:23516,35978:23520,35979:23522,35980:23523,35981:23526,35982:23527,35983:23529,35984:23530,35985:23531,35986:23532,35987:23533,35988:23535,35989:23537,35990:23538,35991:23539,35992:23540,35993:23541,35994:23542,35995:23543,35996:23549,35997:23550,35998:23552,35999:23554,36000:23555,36001:23557,36002:23559,36003:23560,36004:23563,36005:23564,36006:23565,36007:23566,36008:23568,36009:23570,36010:23571,36011:23575,36012:23577,36013:23579,36014:23582,36015:23583,36016:23584,36017:23585,36018:23587,36019:23590,36020:23592,36021:23593,36022:23594,36023:23595,36024:23597,36025:23598,36026:23599,36027:23600,36028:23602,36029:23603,36030:23605,36031:23606,36032:23607,36033:23619,36034:23620,36035:23622,36036:23623,36037:23628,36038:23629,36039:23634,36040:23635,36041:23636,36042:23638,36043:23639,36044:23640,36045:23642,36046:23643,36047:23644,36048:23645,36049:23647,36050:23650,36051:23652,36052:23655,36053:23656,36054:23657,36055:23658,36056:23659,36057:23660,36058:23661,36059:23664,36060:23666,36061:23667,36062:23668,36063:23669,36064:23670,36065:23671,36066:23672,36067:23675,36068:23676,36069:23677,36070:23678,36071:23680,36072:23683,36073:23684,36074:23685,36075:23686,36076:23687,36077:23689,36078:23690,36079:23691,36080:23694,36081:23695,36082:23698,36083:23699,36084:23701,36085:23709,36086:23710,36087:23711,36088:23712,36089:23713,36090:23716,36091:23717,36092:23718,36093:23719,36094:23720,36160:23722,36161:23726,36162:23727,36163:23728,36164:23730,36165:23732,36166:23734,36167:23737,36168:23738,36169:23739,36170:23740,36171:23742,36172:23744,36173:23746,36174:23747,36175:23749,36176:23750,36177:23751,36178:23752,36179:23753,36180:23754,36181:23756,36182:23757,36183:23758,36184:23759,36185:23760,36186:23761,36187:23763,36188:23764,36189:23765,36190:23766,36191:23767,36192:23768,36193:23770,36194:23771,36195:23772,36196:23773,36197:23774,36198:23775,36199:23776,36200:23778,36201:23779,36202:23783,36203:23785,36204:23787,36205:23788,36206:23790,36207:23791,36208:23793,36209:23794,36210:23795,36211:23796,36212:23797,36213:23798,36214:23799,36215:23800,36216:23801,36217:23802,36218:23804,36219:23805,36220:23806,36221:23807,36222:23808,36224:23809,36225:23812,36226:23813,36227:23816,36228:23817,36229:23818,36230:23819,36231:23820,36232:23821,36233:23823,36234:23824,36235:23825,36236:23826,36237:23827,36238:23829,36239:23831,36240:23832,36241:23833,36242:23834,36243:23836,36244:23837,36245:23839,36246:23840,36247:23841,36248:23842,36249:23843,36250:23845,36251:23848,36252:23850,36253:23851,36254:23852,36255:23855,36256:23856,36257:23857,36258:23858,36259:23859,36260:23861,36261:23862,36262:23863,36263:23864,36264:23865,36265:23866,36266:23867,36267:23868,36268:23871,36269:23872,36270:23873,36271:23874,36272:23875,36273:23876,36274:23877,36275:23878,36276:23880,36277:23881,36278:23885,36279:23886,36280:23887,36281:23888,36282:23889,36283:23890,36284:23891,36285:23892,36286:23893,36287:23894,36288:23895,36289:23897,36290:23898,36291:23900,36292:23902,36293:23903,36294:23904,36295:23905,36296:23906,36297:23907,36298:23908,36299:23909,36300:23910,36301:23911,36302:23912,36303:23914,36304:23917,36305:23918,36306:23920,36307:23921,36308:23922,36309:23923,36310:23925,36311:23926,36312:23927,36313:23928,36314:23929,36315:23930,36316:23931,36317:23932,36318:23933,36319:23934,36320:23935,36321:23936,36322:23937,36323:23939,36324:23940,36325:23941,36326:23942,36327:23943,36328:23944,36329:23945,36330:23946,36331:23947,36332:23948,36333:23949,36334:23950,36335:23951,36336:23952,36337:23953,36338:23954,36339:23955,36340:23956,36341:23957,36342:23958,36343:23959,36344:23960,36345:23962,36346:23963,36347:23964,36348:23966,36349:23967,36350:23968,36416:23969,36417:23970,36418:23971,36419:23972,36420:23973,36421:23974,36422:23975,36423:23976,36424:23977,36425:23978,36426:23979,36427:23980,36428:23981,36429:23982,36430:23983,36431:23984,36432:23985,36433:23986,36434:23987,36435:23988,36436:23989,36437:23990,36438:23992,36439:23993,36440:23994,36441:23995,36442:23996,36443:23997,36444:23998,36445:23999,36446:24000,36447:24001,36448:24002,36449:24003,36450:24004,36451:24006,36452:24007,36453:24008,36454:24009,36455:24010,36456:24011,36457:24012,36458:24014,36459:24015,36460:24016,36461:24017,36462:24018,36463:24019,36464:24020,36465:24021,36466:24022,36467:24023,36468:24024,36469:24025,36470:24026,36471:24028,36472:24031,36473:24032,36474:24035,36475:24036,36476:24042,36477:24044,36478:24045,36480:24048,36481:24053,36482:24054,36483:24056,36484:24057,36485:24058,36486:24059,36487:24060,36488:24063,36489:24064,36490:24068,36491:24071,36492:24073,36493:24074,36494:24075,36495:24077,36496:24078,36497:24082,36498:24083,36499:24087,36500:24094,36501:24095,36502:24096,36503:24097,36504:24098,36505:24099,36506:24100,36507:24101,36508:24104,36509:24105,36510:24106,36511:24107,36512:24108,36513:24111,36514:24112,36515:24114,36516:24115,36517:24116,36518:24117,36519:24118,36520:24121,36521:24122,36522:24126,36523:24127,36524:24128,36525:24129,36526:24131,36527:24134,36528:24135,36529:24136,36530:24137,36531:24138,36532:24139,36533:24141,36534:24142,36535:24143,36536:24144,36537:24145,36538:24146,36539:24147,36540:24150,36541:24151,36542:24152,36543:24153,36544:24154,36545:24156,36546:24157,36547:24159,36548:24160,36549:24163,36550:24164,36551:24165,36552:24166,36553:24167,36554:24168,36555:24169,36556:24170,36557:24171,36558:24172,36559:24173,36560:24174,36561:24175,36562:24176,36563:24177,36564:24181,36565:24183,36566:24185,36567:24190,36568:24193,36569:24194,36570:24195,36571:24197,36572:24200,36573:24201,36574:24204,36575:24205,36576:24206,36577:24210,36578:24216,36579:24219,36580:24221,36581:24225,36582:24226,36583:24227,36584:24228,36585:24232,36586:24233,36587:24234,36588:24235,36589:24236,36590:24238,36591:24239,36592:24240,36593:24241,36594:24242,36595:24244,36596:24250,36597:24251,36598:24252,36599:24253,36600:24255,36601:24256,36602:24257,36603:24258,36604:24259,36605:24260,36606:24261,36672:24262,36673:24263,36674:24264,36675:24267,36676:24268,36677:24269,36678:24270,36679:24271,36680:24272,36681:24276,36682:24277,36683:24279,36684:24280,36685:24281,36686:24282,36687:24284,36688:24285,36689:24286,36690:24287,36691:24288,36692:24289,36693:24290,36694:24291,36695:24292,36696:24293,36697:24294,36698:24295,36699:24297,36700:24299,36701:24300,36702:24301,36703:24302,36704:24303,36705:24304,36706:24305,36707:24306,36708:24307,36709:24309,36710:24312,36711:24313,36712:24315,36713:24316,36714:24317,36715:24325,36716:24326,36717:24327,36718:24329,36719:24332,36720:24333,36721:24334,36722:24336,36723:24338,36724:24340,36725:24342,36726:24345,36727:24346,36728:24348,36729:24349,36730:24350,36731:24353,36732:24354,36733:24355,36734:24356,36736:24360,36737:24363,36738:24364,36739:24366,36740:24368,36741:24370,36742:24371,36743:24372,36744:24373,36745:24374,36746:24375,36747:24376,36748:24379,36749:24381,36750:24382,36751:24383,36752:24385,36753:24386,36754:24387,36755:24388,36756:24389,36757:24390,36758:24391,36759:24392,36760:24393,36761:24394,36762:24395,36763:24396,36764:24397,36765:24398,36766:24399,36767:24401,36768:24404,36769:24409,36770:24410,36771:24411,36772:24412,36773:24414,36774:24415,36775:24416,36776:24419,36777:24421,36778:24423,36779:24424,36780:24427,36781:24430,36782:24431,36783:24434,36784:24436,36785:24437,36786:24438,36787:24440,36788:24442,36789:24445,36790:24446,36791:24447,36792:24451,36793:24454,36794:24461,36795:24462,36796:24463,36797:24465,36798:24467,36799:24468,36800:24470,36801:24474,36802:24475,36803:24477,36804:24478,36805:24479,36806:24480,36807:24482,36808:24483,36809:24484,36810:24485,36811:24486,36812:24487,36813:24489,36814:24491,36815:24492,36816:24495,36817:24496,36818:24497,36819:24498,36820:24499,36821:24500,36822:24502,36823:24504,36824:24505,36825:24506,36826:24507,36827:24510,36828:24511,36829:24512,36830:24513,36831:24514,36832:24519,36833:24520,36834:24522,36835:24523,36836:24526,36837:24531,36838:24532,36839:24533,36840:24538,36841:24539,36842:24540,36843:24542,36844:24543,36845:24546,36846:24547,36847:24549,36848:24550,36849:24552,36850:24553,36851:24556,36852:24559,36853:24560,36854:24562,36855:24563,36856:24564,36857:24566,36858:24567,36859:24569,36860:24570,36861:24572,36862:24583,36928:24584,36929:24585,36930:24587,36931:24588,36932:24592,36933:24593,36934:24595,36935:24599,36936:24600,36937:24602,36938:24606,36939:24607,36940:24610,36941:24611,36942:24612,36943:24620,36944:24621,36945:24622,36946:24624,36947:24625,36948:24626,36949:24627,36950:24628,36951:24630,36952:24631,36953:24632,36954:24633,36955:24634,36956:24637,36957:24638,36958:24640,36959:24644,36960:24645,36961:24646,36962:24647,36963:24648,36964:24649,36965:24650,36966:24652,36967:24654,36968:24655,36969:24657,36970:24659,36971:24660,36972:24662,36973:24663,36974:24664,36975:24667,36976:24668,36977:24670,36978:24671,36979:24672,36980:24673,36981:24677,36982:24678,36983:24686,36984:24689,36985:24690,36986:24692,36987:24693,36988:24695,36989:24702,36990:24704,36992:24705,36993:24706,36994:24709,36995:24710,36996:24711,36997:24712,36998:24714,36999:24715,37000:24718,37001:24719,37002:24720,37003:24721,37004:24723,37005:24725,37006:24727,37007:24728,37008:24729,37009:24732,37010:24734,37011:24737,37012:24738,37013:24740,37014:24741,37015:24743,37016:24745,37017:24746,37018:24750,37019:24752,37020:24755,37021:24757,37022:24758,37023:24759,37024:24761,37025:24762,37026:24765,37027:24766,37028:24767,37029:24768,37030:24769,37031:24770,37032:24771,37033:24772,37034:24775,37035:24776,37036:24777,37037:24780,37038:24781,37039:24782,37040:24783,37041:24784,37042:24786,37043:24787,37044:24788,37045:24790,37046:24791,37047:24793,37048:24795,37049:24798,37050:24801,37051:24802,37052:24803,37053:24804,37054:24805,37055:24810,37056:24817,37057:24818,37058:24821,37059:24823,37060:24824,37061:24827,37062:24828,37063:24829,37064:24830,37065:24831,37066:24834,37067:24835,37068:24836,37069:24837,37070:24839,37071:24842,37072:24843,37073:24844,37074:24848,37075:24849,37076:24850,37077:24851,37078:24852,37079:24854,37080:24855,37081:24856,37082:24857,37083:24859,37084:24860,37085:24861,37086:24862,37087:24865,37088:24866,37089:24869,37090:24872,37091:24873,37092:24874,37093:24876,37094:24877,37095:24878,37096:24879,37097:24880,37098:24881,37099:24882,37100:24883,37101:24884,37102:24885,37103:24886,37104:24887,37105:24888,37106:24889,37107:24890,37108:24891,37109:24892,37110:24893,37111:24894,37112:24896,37113:24897,37114:24898,37115:24899,37116:24900,37117:24901,37118:24902,37184:24903,37185:24905,37186:24907,37187:24909,37188:24911,37189:24912,37190:24914,37191:24915,37192:24916,37193:24918,37194:24919,37195:24920,37196:24921,37197:24922,37198:24923,37199:24924,37200:24926,37201:24927,37202:24928,37203:24929,37204:24931,37205:24932,37206:24933,37207:24934,37208:24937,37209:24938,37210:24939,37211:24940,37212:24941,37213:24942,37214:24943,37215:24945,37216:24946,37217:24947,37218:24948,37219:24950,37220:24952,37221:24953,37222:24954,37223:24955,37224:24956,37225:24957,37226:24958,37227:24959,37228:24960,37229:24961,37230:24962,37231:24963,37232:24964,37233:24965,37234:24966,37235:24967,37236:24968,37237:24969,37238:24970,37239:24972,37240:24973,37241:24975,37242:24976,37243:24977,37244:24978,37245:24979,37246:24981,37248:24982,37249:24983,37250:24984,37251:24985,37252:24986,37253:24987,37254:24988,37255:24990,37256:24991,37257:24992,37258:24993,37259:24994,37260:24995,37261:24996,37262:24997,37263:24998,37264:25002,37265:25003,37266:25005,37267:25006,37268:25007,37269:25008,37270:25009,37271:25010,37272:25011,37273:25012,37274:25013,37275:25014,37276:25016,37277:25017,37278:25018,37279:25019,37280:25020,37281:25021,37282:25023,37283:25024,37284:25025,37285:25027,37286:25028,37287:25029,37288:25030,37289:25031,37290:25033,37291:25036,37292:25037,37293:25038,37294:25039,37295:25040,37296:25043,37297:25045,37298:25046,37299:25047,37300:25048,37301:25049,37302:25050,37303:25051,37304:25052,37305:25053,37306:25054,37307:25055,37308:25056,37309:25057,37310:25058,37311:25059,37312:25060,37313:25061,37314:25063,37315:25064,37316:25065,37317:25066,37318:25067,37319:25068,37320:25069,37321:25070,37322:25071,37323:25072,37324:25073,37325:25074,37326:25075,37327:25076,37328:25078,37329:25079,37330:25080,37331:25081,37332:25082,37333:25083,37334:25084,37335:25085,37336:25086,37337:25088,37338:25089,37339:25090,37340:25091,37341:25092,37342:25093,37343:25095,37344:25097,37345:25107,37346:25108,37347:25113,37348:25116,37349:25117,37350:25118,37351:25120,37352:25123,37353:25126,37354:25127,37355:25128,37356:25129,37357:25131,37358:25133,37359:25135,37360:25136,37361:25137,37362:25138,37363:25141,37364:25142,37365:25144,37366:25145,37367:25146,37368:25147,37369:25148,37370:25154,37371:25156,37372:25157,37373:25158,37374:25162,37440:25167,37441:25168,37442:25173,37443:25174,37444:25175,37445:25177,37446:25178,37447:25180,37448:25181,37449:25182,37450:25183,37451:25184,37452:25185,37453:25186,37454:25188,37455:25189,37456:25192,37457:25201,37458:25202,37459:25204,37460:25205,37461:25207,37462:25208,37463:25210,37464:25211,37465:25213,37466:25217,37467:25218,37468:25219,37469:25221,37470:25222,37471:25223,37472:25224,37473:25227,37474:25228,37475:25229,37476:25230,37477:25231,37478:25232,37479:25236,37480:25241,37481:25244,37482:25245,37483:25246,37484:25251,37485:25254,37486:25255,37487:25257,37488:25258,37489:25261,37490:25262,37491:25263,37492:25264,37493:25266,37494:25267,37495:25268,37496:25270,37497:25271,37498:25272,37499:25274,37500:25278,37501:25280,37502:25281,37504:25283,37505:25291,37506:25295,37507:25297,37508:25301,37509:25309,37510:25310,37511:25312,37512:25313,37513:25316,37514:25322,37515:25323,37516:25328,37517:25330,37518:25333,37519:25336,37520:25337,37521:25338,37522:25339,37523:25344,37524:25347,37525:25348,37526:25349,37527:25350,37528:25354,37529:25355,37530:25356,37531:25357,37532:25359,37533:25360,37534:25362,37535:25363,37536:25364,37537:25365,37538:25367,37539:25368,37540:25369,37541:25372,37542:25382,37543:25383,37544:25385,37545:25388,37546:25389,37547:25390,37548:25392,37549:25393,37550:25395,37551:25396,37552:25397,37553:25398,37554:25399,37555:25400,37556:25403,37557:25404,37558:25406,37559:25407,37560:25408,37561:25409,37562:25412,37563:25415,37564:25416,37565:25418,37566:25425,37567:25426,37568:25427,37569:25428,37570:25430,37571:25431,37572:25432,37573:25433,37574:25434,37575:25435,37576:25436,37577:25437,37578:25440,37579:25444,37580:25445,37581:25446,37582:25448,37583:25450,37584:25451,37585:25452,37586:25455,37587:25456,37588:25458,37589:25459,37590:25460,37591:25461,37592:25464,37593:25465,37594:25468,37595:25469,37596:25470,37597:25471,37598:25473,37599:25475,37600:25476,37601:25477,37602:25478,37603:25483,37604:25485,37605:25489,37606:25491,37607:25492,37608:25493,37609:25495,37610:25497,37611:25498,37612:25499,37613:25500,37614:25501,37615:25502,37616:25503,37617:25505,37618:25508,37619:25510,37620:25515,37621:25519,37622:25521,37623:25522,37624:25525,37625:25526,37626:25529,37627:25531,37628:25533,37629:25535,37630:25536,37696:25537,37697:25538,37698:25539,37699:25541,37700:25543,37701:25544,37702:25546,37703:25547,37704:25548,37705:25553,37706:25555,37707:25556,37708:25557,37709:25559,37710:25560,37711:25561,37712:25562,37713:25563,37714:25564,37715:25565,37716:25567,37717:25570,37718:25572,37719:25573,37720:25574,37721:25575,37722:25576,37723:25579,37724:25580,37725:25582,37726:25583,37727:25584,37728:25585,37729:25587,37730:25589,37731:25591,37732:25593,37733:25594,37734:25595,37735:25596,37736:25598,37737:25603,37738:25604,37739:25606,37740:25607,37741:25608,37742:25609,37743:25610,37744:25613,37745:25614,37746:25617,37747:25618,37748:25621,37749:25622,37750:25623,37751:25624,37752:25625,37753:25626,37754:25629,37755:25631,37756:25634,37757:25635,37758:25636,37760:25637,37761:25639,37762:25640,37763:25641,37764:25643,37765:25646,37766:25647,37767:25648,37768:25649,37769:25650,37770:25651,37771:25653,37772:25654,37773:25655,37774:25656,37775:25657,37776:25659,37777:25660,37778:25662,37779:25664,37780:25666,37781:25667,37782:25673,37783:25675,37784:25676,37785:25677,37786:25678,37787:25679,37788:25680,37789:25681,37790:25683,37791:25685,37792:25686,37793:25687,37794:25689,37795:25690,37796:25691,37797:25692,37798:25693,37799:25695,37800:25696,37801:25697,37802:25698,37803:25699,37804:25700,37805:25701,37806:25702,37807:25704,37808:25706,37809:25707,37810:25708,37811:25710,37812:25711,37813:25712,37814:25713,37815:25714,37816:25715,37817:25716,37818:25717,37819:25718,37820:25719,37821:25723,37822:25724,37823:25725,37824:25726,37825:25727,37826:25728,37827:25729,37828:25731,37829:25734,37830:25736,37831:25737,37832:25738,37833:25739,37834:25740,37835:25741,37836:25742,37837:25743,37838:25744,37839:25747,37840:25748,37841:25751,37842:25752,37843:25754,37844:25755,37845:25756,37846:25757,37847:25759,37848:25760,37849:25761,37850:25762,37851:25763,37852:25765,37853:25766,37854:25767,37855:25768,37856:25770,37857:25771,37858:25775,37859:25777,37860:25778,37861:25779,37862:25780,37863:25782,37864:25785,37865:25787,37866:25789,37867:25790,37868:25791,37869:25793,37870:25795,37871:25796,37872:25798,37873:25799,37874:25800,37875:25801,37876:25802,37877:25803,37878:25804,37879:25807,37880:25809,37881:25811,37882:25812,37883:25813,37884:25814,37885:25817,37886:25818,37952:25819,37953:25820,37954:25821,37955:25823,37956:25824,37957:25825,37958:25827,37959:25829,37960:25831,37961:25832,37962:25833,37963:25834,37964:25835,37965:25836,37966:25837,37967:25838,37968:25839,37969:25840,37970:25841,37971:25842,37972:25843,37973:25844,37974:25845,37975:25846,37976:25847,37977:25848,37978:25849,37979:25850,37980:25851,37981:25852,37982:25853,37983:25854,37984:25855,37985:25857,37986:25858,37987:25859,37988:25860,37989:25861,37990:25862,37991:25863,37992:25864,37993:25866,37994:25867,37995:25868,37996:25869,37997:25870,37998:25871,37999:25872,38000:25873,38001:25875,38002:25876,38003:25877,38004:25878,38005:25879,38006:25881,38007:25882,38008:25883,38009:25884,38010:25885,38011:25886,38012:25887,38013:25888,38014:25889,38016:25890,38017:25891,38018:25892,38019:25894,38020:25895,38021:25896,38022:25897,38023:25898,38024:25900,38025:25901,38026:25904,38027:25905,38028:25906,38029:25907,38030:25911,38031:25914,38032:25916,38033:25917,38034:25920,38035:25921,38036:25922,38037:25923,38038:25924,38039:25926,38040:25927,38041:25930,38042:25931,38043:25933,38044:25934,38045:25936,38046:25938,38047:25939,38048:25940,38049:25943,38050:25944,38051:25946,38052:25948,38053:25951,38054:25952,38055:25953,38056:25956,38057:25957,38058:25959,38059:25960,38060:25961,38061:25962,38062:25965,38063:25966,38064:25967,38065:25969,38066:25971,38067:25973,38068:25974,38069:25976,38070:25977,38071:25978,38072:25979,38073:25980,38074:25981,38075:25982,38076:25983,38077:25984,38078:25985,38079:25986,38080:25987,38081:25988,38082:25989,38083:25990,38084:25992,38085:25993,38086:25994,38087:25997,38088:25998,38089:25999,38090:26002,38091:26004,38092:26005,38093:26006,38094:26008,38095:26010,38096:26013,38097:26014,38098:26016,38099:26018,38100:26019,38101:26022,38102:26024,38103:26026,38104:26028,38105:26030,38106:26033,38107:26034,38108:26035,38109:26036,38110:26037,38111:26038,38112:26039,38113:26040,38114:26042,38115:26043,38116:26046,38117:26047,38118:26048,38119:26050,38120:26055,38121:26056,38122:26057,38123:26058,38124:26061,38125:26064,38126:26065,38127:26067,38128:26068,38129:26069,38130:26072,38131:26073,38132:26074,38133:26075,38134:26076,38135:26077,38136:26078,38137:26079,38138:26081,38139:26083,38140:26084,38141:26090,38142:26091,38208:26098,38209:26099,38210:26100,38211:26101,38212:26104,38213:26105,38214:26107,38215:26108,38216:26109,38217:26110,38218:26111,38219:26113,38220:26116,38221:26117,38222:26119,38223:26120,38224:26121,38225:26123,38226:26125,38227:26128,38228:26129,38229:26130,38230:26134,38231:26135,38232:26136,38233:26138,38234:26139,38235:26140,38236:26142,38237:26145,38238:26146,38239:26147,38240:26148,38241:26150,38242:26153,38243:26154,38244:26155,38245:26156,38246:26158,38247:26160,38248:26162,38249:26163,38250:26167,38251:26168,38252:26169,38253:26170,38254:26171,38255:26173,38256:26175,38257:26176,38258:26178,38259:26180,38260:26181,38261:26182,38262:26183,38263:26184,38264:26185,38265:26186,38266:26189,38267:26190,38268:26192,38269:26193,38270:26200,38272:26201,38273:26203,38274:26204,38275:26205,38276:26206,38277:26208,38278:26210,38279:26211,38280:26213,38281:26215,38282:26217,38283:26218,38284:26219,38285:26220,38286:26221,38287:26225,38288:26226,38289:26227,38290:26229,38291:26232,38292:26233,38293:26235,38294:26236,38295:26237,38296:26239,38297:26240,38298:26241,38299:26243,38300:26245,38301:26246,38302:26248,38303:26249,38304:26250,38305:26251,38306:26253,38307:26254,38308:26255,38309:26256,38310:26258,38311:26259,38312:26260,38313:26261,38314:26264,38315:26265,38316:26266,38317:26267,38318:26268,38319:26270,38320:26271,38321:26272,38322:26273,38323:26274,38324:26275,38325:26276,38326:26277,38327:26278,38328:26281,38329:26282,38330:26283,38331:26284,38332:26285,38333:26287,38334:26288,38335:26289,38336:26290,38337:26291,38338:26293,38339:26294,38340:26295,38341:26296,38342:26298,38343:26299,38344:26300,38345:26301,38346:26303,38347:26304,38348:26305,38349:26306,38350:26307,38351:26308,38352:26309,38353:26310,38354:26311,38355:26312,38356:26313,38357:26314,38358:26315,38359:26316,38360:26317,38361:26318,38362:26319,38363:26320,38364:26321,38365:26322,38366:26323,38367:26324,38368:26325,38369:26326,38370:26327,38371:26328,38372:26330,38373:26334,38374:26335,38375:26336,38376:26337,38377:26338,38378:26339,38379:26340,38380:26341,38381:26343,38382:26344,38383:26346,38384:26347,38385:26348,38386:26349,38387:26350,38388:26351,38389:26353,38390:26357,38391:26358,38392:26360,38393:26362,38394:26363,38395:26365,38396:26369,38397:26370,38398:26371,38464:26372,38465:26373,38466:26374,38467:26375,38468:26380,38469:26382,38470:26383,38471:26385,38472:26386,38473:26387,38474:26390,38475:26392,38476:26393,38477:26394,38478:26396,38479:26398,38480:26400,38481:26401,38482:26402,38483:26403,38484:26404,38485:26405,38486:26407,38487:26409,38488:26414,38489:26416,38490:26418,38491:26419,38492:26422,38493:26423,38494:26424,38495:26425,38496:26427,38497:26428,38498:26430,38499:26431,38500:26433,38501:26436,38502:26437,38503:26439,38504:26442,38505:26443,38506:26445,38507:26450,38508:26452,38509:26453,38510:26455,38511:26456,38512:26457,38513:26458,38514:26459,38515:26461,38516:26466,38517:26467,38518:26468,38519:26470,38520:26471,38521:26475,38522:26476,38523:26478,38524:26481,38525:26484,38526:26486,38528:26488,38529:26489,38530:26490,38531:26491,38532:26493,38533:26496,38534:26498,38535:26499,38536:26501,38537:26502,38538:26504,38539:26506,38540:26508,38541:26509,38542:26510,38543:26511,38544:26513,38545:26514,38546:26515,38547:26516,38548:26518,38549:26521,38550:26523,38551:26527,38552:26528,38553:26529,38554:26532,38555:26534,38556:26537,38557:26540,38558:26542,38559:26545,38560:26546,38561:26548,38562:26553,38563:26554,38564:26555,38565:26556,38566:26557,38567:26558,38568:26559,38569:26560,38570:26562,38571:26565,38572:26566,38573:26567,38574:26568,38575:26569,38576:26570,38577:26571,38578:26572,38579:26573,38580:26574,38581:26581,38582:26582,38583:26583,38584:26587,38585:26591,38586:26593,38587:26595,38588:26596,38589:26598,38590:26599,38591:26600,38592:26602,38593:26603,38594:26605,38595:26606,38596:26610,38597:26613,38598:26614,38599:26615,38600:26616,38601:26617,38602:26618,38603:26619,38604:26620,38605:26622,38606:26625,38607:26626,38608:26627,38609:26628,38610:26630,38611:26637,38612:26640,38613:26642,38614:26644,38615:26645,38616:26648,38617:26649,38618:26650,38619:26651,38620:26652,38621:26654,38622:26655,38623:26656,38624:26658,38625:26659,38626:26660,38627:26661,38628:26662,38629:26663,38630:26664,38631:26667,38632:26668,38633:26669,38634:26670,38635:26671,38636:26672,38637:26673,38638:26676,38639:26677,38640:26678,38641:26682,38642:26683,38643:26687,38644:26695,38645:26699,38646:26701,38647:26703,38648:26706,38649:26710,38650:26711,38651:26712,38652:26713,38653:26714,38654:26715,38720:26716,38721:26717,38722:26718,38723:26719,38724:26730,38725:26732,38726:26733,38727:26734,38728:26735,38729:26736,38730:26737,38731:26738,38732:26739,38733:26741,38734:26744,38735:26745,38736:26746,38737:26747,38738:26748,38739:26749,38740:26750,38741:26751,38742:26752,38743:26754,38744:26756,38745:26759,38746:26760,38747:26761,38748:26762,38749:26763,38750:26764,38751:26765,38752:26766,38753:26768,38754:26769,38755:26770,38756:26772,38757:26773,38758:26774,38759:26776,38760:26777,38761:26778,38762:26779,38763:26780,38764:26781,38765:26782,38766:26783,38767:26784,38768:26785,38769:26787,38770:26788,38771:26789,38772:26793,38773:26794,38774:26795,38775:26796,38776:26798,38777:26801,38778:26802,38779:26804,38780:26806,38781:26807,38782:26808,38784:26809,38785:26810,38786:26811,38787:26812,38788:26813,38789:26814,38790:26815,38791:26817,38792:26819,38793:26820,38794:26821,38795:26822,38796:26823,38797:26824,38798:26826,38799:26828,38800:26830,38801:26831,38802:26832,38803:26833,38804:26835,38805:26836,38806:26838,38807:26839,38808:26841,38809:26843,38810:26844,38811:26845,38812:26846,38813:26847,38814:26849,38815:26850,38816:26852,38817:26853,38818:26854,38819:26855,38820:26856,38821:26857,38822:26858,38823:26859,38824:26860,38825:26861,38826:26863,38827:26866,38828:26867,38829:26868,38830:26870,38831:26871,38832:26872,38833:26875,38834:26877,38835:26878,38836:26879,38837:26880,38838:26882,38839:26883,38840:26884,38841:26886,38842:26887,38843:26888,38844:26889,38845:26890,38846:26892,38847:26895,38848:26897,38849:26899,38850:26900,38851:26901,38852:26902,38853:26903,38854:26904,38855:26905,38856:26906,38857:26907,38858:26908,38859:26909,38860:26910,38861:26913,38862:26914,38863:26915,38864:26917,38865:26918,38866:26919,38867:26920,38868:26921,38869:26922,38870:26923,38871:26924,38872:26926,38873:26927,38874:26929,38875:26930,38876:26931,38877:26933,38878:26934,38879:26935,38880:26936,38881:26938,38882:26939,38883:26940,38884:26942,38885:26944,38886:26945,38887:26947,38888:26948,38889:26949,38890:26950,38891:26951,38892:26952,38893:26953,38894:26954,38895:26955,38896:26956,38897:26957,38898:26958,38899:26959,38900:26960,38901:26961,38902:26962,38903:26963,38904:26965,38905:26966,38906:26968,38907:26969,38908:26971,38909:26972,38910:26975,38976:26977,38977:26978,38978:26980,38979:26981,38980:26983,38981:26984,38982:26985,38983:26986,38984:26988,38985:26989,38986:26991,38987:26992,38988:26994,38989:26995,38990:26996,38991:26997,38992:26998,38993:27002,38994:27003,38995:27005,38996:27006,38997:27007,38998:27009,38999:27011,39000:27013,39001:27018,39002:27019,39003:27020,39004:27022,39005:27023,39006:27024,39007:27025,39008:27026,39009:27027,39010:27030,39011:27031,39012:27033,39013:27034,39014:27037,39015:27038,39016:27039,39017:27040,39018:27041,39019:27042,39020:27043,39021:27044,39022:27045,39023:27046,39024:27049,39025:27050,39026:27052,39027:27054,39028:27055,39029:27056,39030:27058,39031:27059,39032:27061,39033:27062,39034:27064,39035:27065,39036:27066,39037:27068,39038:27069,39040:27070,39041:27071,39042:27072,39043:27074,39044:27075,39045:27076,39046:27077,39047:27078,39048:27079,39049:27080,39050:27081,39051:27083,39052:27085,39053:27087,39054:27089,39055:27090,39056:27091,39057:27093,39058:27094,39059:27095,39060:27096,39061:27097,39062:27098,39063:27100,39064:27101,39065:27102,39066:27105,39067:27106,39068:27107,39069:27108,39070:27109,39071:27110,39072:27111,39073:27112,39074:27113,39075:27114,39076:27115,39077:27116,39078:27118,39079:27119,39080:27120,39081:27121,39082:27123,39083:27124,39084:27125,39085:27126,39086:27127,39087:27128,39088:27129,39089:27130,39090:27131,39091:27132,39092:27134,39093:27136,39094:27137,39095:27138,39096:27139,39097:27140,39098:27141,39099:27142,39100:27143,39101:27144,39102:27145,39103:27147,39104:27148,39105:27149,39106:27150,39107:27151,39108:27152,39109:27153,39110:27154,39111:27155,39112:27156,39113:27157,39114:27158,39115:27161,39116:27162,39117:27163,39118:27164,39119:27165,39120:27166,39121:27168,39122:27170,39123:27171,39124:27172,39125:27173,39126:27174,39127:27175,39128:27177,39129:27179,39130:27180,39131:27181,39132:27182,39133:27184,39134:27186,39135:27187,39136:27188,39137:27190,39138:27191,39139:27192,39140:27193,39141:27194,39142:27195,39143:27196,39144:27199,39145:27200,39146:27201,39147:27202,39148:27203,39149:27205,39150:27206,39151:27208,39152:27209,39153:27210,39154:27211,39155:27212,39156:27213,39157:27214,39158:27215,39159:27217,39160:27218,39161:27219,39162:27220,39163:27221,39164:27222,39165:27223,39166:27226,39232:27228,39233:27229,39234:27230,39235:27231,39236:27232,39237:27234,39238:27235,39239:27236,39240:27238,39241:27239,39242:27240,39243:27241,39244:27242,39245:27243,39246:27244,39247:27245,39248:27246,39249:27247,39250:27248,39251:27250,39252:27251,39253:27252,39254:27253,39255:27254,39256:27255,39257:27256,39258:27258,39259:27259,39260:27261,39261:27262,39262:27263,39263:27265,39264:27266,39265:27267,39266:27269,39267:27270,39268:27271,39269:27272,39270:27273,39271:27274,39272:27275,39273:27276,39274:27277,39275:27279,39276:27282,39277:27283,39278:27284,39279:27285,39280:27286,39281:27288,39282:27289,39283:27290,39284:27291,39285:27292,39286:27293,39287:27294,39288:27295,39289:27297,39290:27298,39291:27299,39292:27300,39293:27301,39294:27302,39296:27303,39297:27304,39298:27306,39299:27309,39300:27310,39301:27311,39302:27312,39303:27313,39304:27314,39305:27315,39306:27316,39307:27317,39308:27318,39309:27319,39310:27320,39311:27321,39312:27322,39313:27323,39314:27324,39315:27325,39316:27326,39317:27327,39318:27328,39319:27329,39320:27330,39321:27331,39322:27332,39323:27333,39324:27334,39325:27335,39326:27336,39327:27337,39328:27338,39329:27339,39330:27340,39331:27341,39332:27342,39333:27343,39334:27344,39335:27345,39336:27346,39337:27347,39338:27348,39339:27349,39340:27350,39341:27351,39342:27352,39343:27353,39344:27354,39345:27355,39346:27356,39347:27357,39348:27358,39349:27359,39350:27360,39351:27361,39352:27362,39353:27363,39354:27364,39355:27365,39356:27366,39357:27367,39358:27368,39359:27369,39360:27370,39361:27371,39362:27372,39363:27373,39364:27374,39365:27375,39366:27376,39367:27377,39368:27378,39369:27379,39370:27380,39371:27381,39372:27382,39373:27383,39374:27384,39375:27385,39376:27386,39377:27387,39378:27388,39379:27389,39380:27390,39381:27391,39382:27392,39383:27393,39384:27394,39385:27395,39386:27396,39387:27397,39388:27398,39389:27399,39390:27400,39391:27401,39392:27402,39393:27403,39394:27404,39395:27405,39396:27406,39397:27407,39398:27408,39399:27409,39400:27410,39401:27411,39402:27412,39403:27413,39404:27414,39405:27415,39406:27416,39407:27417,39408:27418,39409:27419,39410:27420,39411:27421,39412:27422,39413:27423,39414:27429,39415:27430,39416:27432,39417:27433,39418:27434,39419:27435,39420:27436,39421:27437,39422:27438,39488:27439,39489:27440,39490:27441,39491:27443,39492:27444,39493:27445,39494:27446,39495:27448,39496:27451,39497:27452,39498:27453,39499:27455,39500:27456,39501:27457,39502:27458,39503:27460,39504:27461,39505:27464,39506:27466,39507:27467,39508:27469,39509:27470,39510:27471,39511:27472,39512:27473,39513:27474,39514:27475,39515:27476,39516:27477,39517:27478,39518:27479,39519:27480,39520:27482,39521:27483,39522:27484,39523:27485,39524:27486,39525:27487,39526:27488,39527:27489,39528:27496,39529:27497,39530:27499,39531:27500,39532:27501,39533:27502,39534:27503,39535:27504,39536:27505,39537:27506,39538:27507,39539:27508,39540:27509,39541:27510,39542:27511,39543:27512,39544:27514,39545:27517,39546:27518,39547:27519,39548:27520,39549:27525,39550:27528,39552:27532,39553:27534,39554:27535,39555:27536,39556:27537,39557:27540,39558:27541,39559:27543,39560:27544,39561:27545,39562:27548,39563:27549,39564:27550,39565:27551,39566:27552,39567:27554,39568:27555,39569:27556,39570:27557,39571:27558,39572:27559,39573:27560,39574:27561,39575:27563,39576:27564,39577:27565,39578:27566,39579:27567,39580:27568,39581:27569,39582:27570,39583:27574,39584:27576,39585:27577,39586:27578,39587:27579,39588:27580,39589:27581,39590:27582,39591:27584,39592:27587,39593:27588,39594:27590,39595:27591,39596:27592,39597:27593,39598:27594,39599:27596,39600:27598,39601:27600,39602:27601,39603:27608,39604:27610,39605:27612,39606:27613,39607:27614,39608:27615,39609:27616,39610:27618,39611:27619,39612:27620,39613:27621,39614:27622,39615:27623,39616:27624,39617:27625,39618:27628,39619:27629,39620:27630,39621:27632,39622:27633,39623:27634,39624:27636,39625:27638,39626:27639,39627:27640,39628:27642,39629:27643,39630:27644,39631:27646,39632:27647,39633:27648,39634:27649,39635:27650,39636:27651,39637:27652,39638:27656,39639:27657,39640:27658,39641:27659,39642:27660,39643:27662,39644:27666,39645:27671,39646:27676,39647:27677,39648:27678,39649:27680,39650:27683,39651:27685,39652:27691,39653:27692,39654:27693,39655:27697,39656:27699,39657:27702,39658:27703,39659:27705,39660:27706,39661:27707,39662:27708,39663:27710,39664:27711,39665:27715,39666:27716,39667:27717,39668:27720,39669:27723,39670:27724,39671:27725,39672:27726,39673:27727,39674:27729,39675:27730,39676:27731,39677:27734,39678:27736,39744:27737,39745:27738,39746:27746,39747:27747,39748:27749,39749:27750,39750:27751,39751:27755,39752:27756,39753:27757,39754:27758,39755:27759,39756:27761,39757:27763,39758:27765,39759:27767,39760:27768,39761:27770,39762:27771,39763:27772,39764:27775,39765:27776,39766:27780,39767:27783,39768:27786,39769:27787,39770:27789,39771:27790,39772:27793,39773:27794,39774:27797,39775:27798,39776:27799,39777:27800,39778:27802,39779:27804,39780:27805,39781:27806,39782:27808,39783:27810,39784:27816,39785:27820,39786:27823,39787:27824,39788:27828,39789:27829,39790:27830,39791:27831,39792:27834,39793:27840,39794:27841,39795:27842,39796:27843,39797:27846,39798:27847,39799:27848,39800:27851,39801:27853,39802:27854,39803:27855,39804:27857,39805:27858,39806:27864,39808:27865,39809:27866,39810:27868,39811:27869,39812:27871,39813:27876,39814:27878,39815:27879,39816:27881,39817:27884,39818:27885,39819:27890,39820:27892,39821:27897,39822:27903,39823:27904,39824:27906,39825:27907,39826:27909,39827:27910,39828:27912,39829:27913,39830:27914,39831:27917,39832:27919,39833:27920,39834:27921,39835:27923,39836:27924,39837:27925,39838:27926,39839:27928,39840:27932,39841:27933,39842:27935,39843:27936,39844:27937,39845:27938,39846:27939,39847:27940,39848:27942,39849:27944,39850:27945,39851:27948,39852:27949,39853:27951,39854:27952,39855:27956,39856:27958,39857:27959,39858:27960,39859:27962,39860:27967,39861:27968,39862:27970,39863:27972,39864:27977,39865:27980,39866:27984,39867:27989,39868:27990,39869:27991,39870:27992,39871:27995,39872:27997,39873:27999,39874:28001,39875:28002,39876:28004,39877:28005,39878:28007,39879:28008,39880:28011,39881:28012,39882:28013,39883:28016,39884:28017,39885:28018,39886:28019,39887:28021,39888:28022,39889:28025,39890:28026,39891:28027,39892:28029,39893:28030,39894:28031,39895:28032,39896:28033,39897:28035,39898:28036,39899:28038,39900:28039,39901:28042,39902:28043,39903:28045,39904:28047,39905:28048,39906:28050,39907:28054,39908:28055,39909:28056,39910:28057,39911:28058,39912:28060,39913:28066,39914:28069,39915:28076,39916:28077,39917:28080,39918:28081,39919:28083,39920:28084,39921:28086,39922:28087,39923:28089,39924:28090,39925:28091,39926:28092,39927:28093,39928:28094,39929:28097,39930:28098,39931:28099,39932:28104,39933:28105,39934:28106,40000:28109,40001:28110,40002:28111,40003:28112,40004:28114,40005:28115,40006:28116,40007:28117,40008:28119,40009:28122,40010:28123,40011:28124,40012:28127,40013:28130,40014:28131,40015:28133,40016:28135,40017:28136,40018:28137,40019:28138,40020:28141,40021:28143,40022:28144,40023:28146,40024:28148,40025:28149,40026:28150,40027:28152,40028:28154,40029:28157,40030:28158,40031:28159,40032:28160,40033:28161,40034:28162,40035:28163,40036:28164,40037:28166,40038:28167,40039:28168,40040:28169,40041:28171,40042:28175,40043:28178,40044:28179,40045:28181,40046:28184,40047:28185,40048:28187,40049:28188,40050:28190,40051:28191,40052:28194,40053:28198,40054:28199,40055:28200,40056:28202,40057:28204,40058:28206,40059:28208,40060:28209,40061:28211,40062:28213,40064:28214,40065:28215,40066:28217,40067:28219,40068:28220,40069:28221,40070:28222,40071:28223,40072:28224,40073:28225,40074:28226,40075:28229,40076:28230,40077:28231,40078:28232,40079:28233,40080:28234,40081:28235,40082:28236,40083:28239,40084:28240,40085:28241,40086:28242,40087:28245,40088:28247,40089:28249,40090:28250,40091:28252,40092:28253,40093:28254,40094:28256,40095:28257,40096:28258,40097:28259,40098:28260,40099:28261,40100:28262,40101:28263,40102:28264,40103:28265,40104:28266,40105:28268,40106:28269,40107:28271,40108:28272,40109:28273,40110:28274,40111:28275,40112:28276,40113:28277,40114:28278,40115:28279,40116:28280,40117:28281,40118:28282,40119:28283,40120:28284,40121:28285,40122:28288,40123:28289,40124:28290,40125:28292,40126:28295,40127:28296,40128:28298,40129:28299,40130:28300,40131:28301,40132:28302,40133:28305,40134:28306,40135:28307,40136:28308,40137:28309,40138:28310,40139:28311,40140:28313,40141:28314,40142:28315,40143:28317,40144:28318,40145:28320,40146:28321,40147:28323,40148:28324,40149:28326,40150:28328,40151:28329,40152:28331,40153:28332,40154:28333,40155:28334,40156:28336,40157:28339,40158:28341,40159:28344,40160:28345,40161:28348,40162:28350,40163:28351,40164:28352,40165:28355,40166:28356,40167:28357,40168:28358,40169:28360,40170:28361,40171:28362,40172:28364,40173:28365,40174:28366,40175:28368,40176:28370,40177:28374,40178:28376,40179:28377,40180:28379,40181:28380,40182:28381,40183:28387,40184:28391,40185:28394,40186:28395,40187:28396,40188:28397,40189:28398,40190:28399,40256:28400,40257:28401,40258:28402,40259:28403,40260:28405,40261:28406,40262:28407,40263:28408,40264:28410,40265:28411,40266:28412,40267:28413,40268:28414,40269:28415,40270:28416,40271:28417,40272:28419,40273:28420,40274:28421,40275:28423,40276:28424,40277:28426,40278:28427,40279:28428,40280:28429,40281:28430,40282:28432,40283:28433,40284:28434,40285:28438,40286:28439,40287:28440,40288:28441,40289:28442,40290:28443,40291:28444,40292:28445,40293:28446,40294:28447,40295:28449,40296:28450,40297:28451,40298:28453,40299:28454,40300:28455,40301:28456,40302:28460,40303:28462,40304:28464,40305:28466,40306:28468,40307:28469,40308:28471,40309:28472,40310:28473,40311:28474,40312:28475,40313:28476,40314:28477,40315:28479,40316:28480,40317:28481,40318:28482,40320:28483,40321:28484,40322:28485,40323:28488,40324:28489,40325:28490,40326:28492,40327:28494,40328:28495,40329:28496,40330:28497,40331:28498,40332:28499,40333:28500,40334:28501,40335:28502,40336:28503,40337:28505,40338:28506,40339:28507,40340:28509,40341:28511,40342:28512,40343:28513,40344:28515,40345:28516,40346:28517,40347:28519,40348:28520,40349:28521,40350:28522,40351:28523,40352:28524,40353:28527,40354:28528,40355:28529,40356:28531,40357:28533,40358:28534,40359:28535,40360:28537,40361:28539,40362:28541,40363:28542,40364:28543,40365:28544,40366:28545,40367:28546,40368:28547,40369:28549,40370:28550,40371:28551,40372:28554,40373:28555,40374:28559,40375:28560,40376:28561,40377:28562,40378:28563,40379:28564,40380:28565,40381:28566,40382:28567,40383:28568,40384:28569,40385:28570,40386:28571,40387:28573,40388:28574,40389:28575,40390:28576,40391:28578,40392:28579,40393:28580,40394:28581,40395:28582,40396:28584,40397:28585,40398:28586,40399:28587,40400:28588,40401:28589,40402:28590,40403:28591,40404:28592,40405:28593,40406:28594,40407:28596,40408:28597,40409:28599,40410:28600,40411:28602,40412:28603,40413:28604,40414:28605,40415:28606,40416:28607,40417:28609,40418:28611,40419:28612,40420:28613,40421:28614,40422:28615,40423:28616,40424:28618,40425:28619,40426:28620,40427:28621,40428:28622,40429:28623,40430:28624,40431:28627,40432:28628,40433:28629,40434:28630,40435:28631,40436:28632,40437:28633,40438:28634,40439:28635,40440:28636,40441:28637,40442:28639,40443:28642,40444:28643,40445:28644,40446:28645,40512:28646,40513:28647,40514:28648,40515:28649,40516:28650,40517:28651,40518:28652,40519:28653,40520:28656,40521:28657,40522:28658,40523:28659,40524:28660,40525:28661,40526:28662,40527:28663,40528:28664,40529:28665,40530:28666,40531:28667,40532:28668,40533:28669,40534:28670,40535:28671,40536:28672,40537:28673,40538:28674,40539:28675,40540:28676,40541:28677,40542:28678,40543:28679,40544:28680,40545:28681,40546:28682,40547:28683,40548:28684,40549:28685,40550:28686,40551:28687,40552:28688,40553:28690,40554:28691,40555:28692,40556:28693,40557:28694,40558:28695,40559:28696,40560:28697,40561:28700,40562:28701,40563:28702,40564:28703,40565:28704,40566:28705,40567:28706,40568:28708,40569:28709,40570:28710,40571:28711,40572:28712,40573:28713,40574:28714,40576:28715,40577:28716,40578:28717,40579:28718,40580:28719,40581:28720,40582:28721,40583:28722,40584:28723,40585:28724,40586:28726,40587:28727,40588:28728,40589:28730,40590:28731,40591:28732,40592:28733,40593:28734,40594:28735,40595:28736,40596:28737,40597:28738,40598:28739,40599:28740,40600:28741,40601:28742,40602:28743,40603:28744,40604:28745,40605:28746,40606:28747,40607:28749,40608:28750,40609:28752,40610:28753,40611:28754,40612:28755,40613:28756,40614:28757,40615:28758,40616:28759,40617:28760,40618:28761,40619:28762,40620:28763,40621:28764,40622:28765,40623:28767,40624:28768,40625:28769,40626:28770,40627:28771,40628:28772,40629:28773,40630:28774,40631:28775,40632:28776,40633:28777,40634:28778,40635:28782,40636:28785,40637:28786,40638:28787,40639:28788,40640:28791,40641:28793,40642:28794,40643:28795,40644:28797,40645:28801,40646:28802,40647:28803,40648:28804,40649:28806,40650:28807,40651:28808,40652:28811,40653:28812,40654:28813,40655:28815,40656:28816,40657:28817,40658:28819,40659:28823,40660:28824,40661:28826,40662:28827,40663:28830,40664:28831,40665:28832,40666:28833,40667:28834,40668:28835,40669:28836,40670:28837,40671:28838,40672:28839,40673:28840,40674:28841,40675:28842,40676:28848,40677:28850,40678:28852,40679:28853,40680:28854,40681:28858,40682:28862,40683:28863,40684:28868,40685:28869,40686:28870,40687:28871,40688:28873,40689:28875,40690:28876,40691:28877,40692:28878,40693:28879,40694:28880,40695:28881,40696:28882,40697:28883,40698:28884,40699:28885,40700:28886,40701:28887,40702:28890,40768:28892,40769:28893,40770:28894,40771:28896,40772:28897,40773:28898,40774:28899,40775:28901,40776:28906,40777:28910,40778:28912,40779:28913,40780:28914,40781:28915,40782:28916,40783:28917,40784:28918,40785:28920,40786:28922,40787:28923,40788:28924,40789:28926,40790:28927,40791:28928,40792:28929,40793:28930,40794:28931,40795:28932,40796:28933,40797:28934,40798:28935,40799:28936,40800:28939,40801:28940,40802:28941,40803:28942,40804:28943,40805:28945,40806:28946,40807:28948,40808:28951,40809:28955,40810:28956,40811:28957,40812:28958,40813:28959,40814:28960,40815:28961,40816:28962,40817:28963,40818:28964,40819:28965,40820:28967,40821:28968,40822:28969,40823:28970,40824:28971,40825:28972,40826:28973,40827:28974,40828:28978,40829:28979,40830:28980,40832:28981,40833:28983,40834:28984,40835:28985,40836:28986,40837:28987,40838:28988,40839:28989,40840:28990,40841:28991,40842:28992,40843:28993,40844:28994,40845:28995,40846:28996,40847:28998,40848:28999,40849:29000,40850:29001,40851:29003,40852:29005,40853:29007,40854:29008,40855:29009,40856:29010,40857:29011,40858:29012,40859:29013,40860:29014,40861:29015,40862:29016,40863:29017,40864:29018,40865:29019,40866:29021,40867:29023,40868:29024,40869:29025,40870:29026,40871:29027,40872:29029,40873:29033,40874:29034,40875:29035,40876:29036,40877:29037,40878:29039,40879:29040,40880:29041,40881:29044,40882:29045,40883:29046,40884:29047,40885:29049,40886:29051,40887:29052,40888:29054,40889:29055,40890:29056,40891:29057,40892:29058,40893:29059,40894:29061,40895:29062,40896:29063,40897:29064,40898:29065,40899:29067,40900:29068,40901:29069,40902:29070,40903:29072,40904:29073,40905:29074,40906:29075,40907:29077,40908:29078,40909:29079,40910:29082,40911:29083,40912:29084,40913:29085,40914:29086,40915:29089,40916:29090,40917:29091,40918:29092,40919:29093,40920:29094,40921:29095,40922:29097,40923:29098,40924:29099,40925:29101,40926:29102,40927:29103,40928:29104,40929:29105,40930:29106,40931:29108,40932:29110,40933:29111,40934:29112,40935:29114,40936:29115,40937:29116,40938:29117,40939:29118,40940:29119,40941:29120,40942:29121,40943:29122,40944:29124,40945:29125,40946:29126,40947:29127,40948:29128,40949:29129,40950:29130,40951:29131,40952:29132,40953:29133,40954:29135,40955:29136,40956:29137,40957:29138,40958:29139,41024:29142,41025:29143,41026:29144,41027:29145,41028:29146,41029:29147,41030:29148,41031:29149,41032:29150,41033:29151,41034:29153,41035:29154,41036:29155,41037:29156,41038:29158,41039:29160,41040:29161,41041:29162,41042:29163,41043:29164,41044:29165,41045:29167,41046:29168,41047:29169,41048:29170,41049:29171,41050:29172,41051:29173,41052:29174,41053:29175,41054:29176,41055:29178,41056:29179,41057:29180,41058:29181,41059:29182,41060:29183,41061:29184,41062:29185,41063:29186,41064:29187,41065:29188,41066:29189,41067:29191,41068:29192,41069:29193,41070:29194,41071:29195,41072:29196,41073:29197,41074:29198,41075:29199,41076:29200,41077:29201,41078:29202,41079:29203,41080:29204,41081:29205,41082:29206,41083:29207,41084:29208,41085:29209,41086:29210,41088:29211,41089:29212,41090:29214,41091:29215,41092:29216,41093:29217,41094:29218,41095:29219,41096:29220,41097:29221,41098:29222,41099:29223,41100:29225,41101:29227,41102:29229,41103:29230,41104:29231,41105:29234,41106:29235,41107:29236,41108:29242,41109:29244,41110:29246,41111:29248,41112:29249,41113:29250,41114:29251,41115:29252,41116:29253,41117:29254,41118:29257,41119:29258,41120:29259,41121:29262,41122:29263,41123:29264,41124:29265,41125:29267,41126:29268,41127:29269,41128:29271,41129:29272,41130:29274,41131:29276,41132:29278,41133:29280,41134:29283,41135:29284,41136:29285,41137:29288,41138:29290,41139:29291,41140:29292,41141:29293,41142:29296,41143:29297,41144:29299,41145:29300,41146:29302,41147:29303,41148:29304,41149:29307,41150:29308,41151:29309,41152:29314,41153:29315,41154:29317,41155:29318,41156:29319,41157:29320,41158:29321,41159:29324,41160:29326,41161:29328,41162:29329,41163:29331,41164:29332,41165:29333,41166:29334,41167:29335,41168:29336,41169:29337,41170:29338,41171:29339,41172:29340,41173:29341,41174:29342,41175:29344,41176:29345,41177:29346,41178:29347,41179:29348,41180:29349,41181:29350,41182:29351,41183:29352,41184:29353,41185:29354,41186:29355,41187:29358,41188:29361,41189:29362,41190:29363,41191:29365,41192:29370,41193:29371,41194:29372,41195:29373,41196:29374,41197:29375,41198:29376,41199:29381,41200:29382,41201:29383,41202:29385,41203:29386,41204:29387,41205:29388,41206:29391,41207:29393,41208:29395,41209:29396,41210:29397,41211:29398,41212:29400,41213:29402,41214:29403,41280:58566,41281:58567,41282:58568,41283:58569,41284:58570,41285:58571,41286:58572,41287:58573,41288:58574,41289:58575,41290:58576,41291:58577,41292:58578,41293:58579,41294:58580,41295:58581,41296:58582,41297:58583,41298:58584,41299:58585,41300:58586,41301:58587,41302:58588,41303:58589,41304:58590,41305:58591,41306:58592,41307:58593,41308:58594,41309:58595,41310:58596,41311:58597,41312:58598,41313:58599,41314:58600,41315:58601,41316:58602,41317:58603,41318:58604,41319:58605,41320:58606,41321:58607,41322:58608,41323:58609,41324:58610,41325:58611,41326:58612,41327:58613,41328:58614,41329:58615,41330:58616,41331:58617,41332:58618,41333:58619,41334:58620,41335:58621,41336:58622,41337:58623,41338:58624,41339:58625,41340:58626,41341:58627,41342:58628,41344:58629,41345:58630,41346:58631,41347:58632,41348:58633,41349:58634,41350:58635,41351:58636,41352:58637,41353:58638,41354:58639,41355:58640,41356:58641,41357:58642,41358:58643,41359:58644,41360:58645,41361:58646,41362:58647,41363:58648,41364:58649,41365:58650,41366:58651,41367:58652,41368:58653,41369:58654,41370:58655,41371:58656,41372:58657,41373:58658,41374:58659,41375:58660,41376:58661,41377:12288,41378:12289,41379:12290,41380:183,41381:713,41382:711,41383:168,41384:12291,41385:12293,41386:8212,41387:65374,41388:8214,41389:8230,41390:8216,41391:8217,41392:8220,41393:8221,41394:12308,41395:12309,41396:12296,41397:12297,41398:12298,41399:12299,41400:12300,41401:12301,41402:12302,41403:12303,41404:12310,41405:12311,41406:12304,41407:12305,41408:177,41409:215,41410:247,41411:8758,41412:8743,41413:8744,41414:8721,41415:8719,41416:8746,41417:8745,41418:8712,41419:8759,41420:8730,41421:8869,41422:8741,41423:8736,41424:8978,41425:8857,41426:8747,41427:8750,41428:8801,41429:8780,41430:8776,41431:8765,41432:8733,41433:8800,41434:8814,41435:8815,41436:8804,41437:8805,41438:8734,41439:8757,41440:8756,41441:9794,41442:9792,41443:176,41444:8242,41445:8243,41446:8451,41447:65284,41448:164,41449:65504,41450:65505,41451:8240,41452:167,41453:8470,41454:9734,41455:9733,41456:9675,41457:9679,41458:9678,41459:9671,41460:9670,41461:9633,41462:9632,41463:9651,41464:9650,41465:8251,41466:8594,41467:8592,41468:8593,41469:8595,41470:12307,41536:58662,41537:58663,41538:58664,41539:58665,41540:58666,41541:58667,41542:58668,41543:58669,41544:58670,41545:58671,41546:58672,41547:58673,41548:58674,41549:58675,41550:58676,41551:58677,41552:58678,41553:58679,41554:58680,41555:58681,41556:58682,41557:58683,41558:58684,41559:58685,41560:58686,41561:58687,41562:58688,41563:58689,41564:58690,41565:58691,41566:58692,41567:58693,41568:58694,41569:58695,41570:58696,41571:58697,41572:58698,41573:58699,41574:58700,41575:58701,41576:58702,41577:58703,41578:58704,41579:58705,41580:58706,41581:58707,41582:58708,41583:58709,41584:58710,41585:58711,41586:58712,41587:58713,41588:58714,41589:58715,41590:58716,41591:58717,41592:58718,41593:58719,41594:58720,41595:58721,41596:58722,41597:58723,41598:58724,41600:58725,41601:58726,41602:58727,41603:58728,41604:58729,41605:58730,41606:58731,41607:58732,41608:58733,41609:58734,41610:58735,41611:58736,41612:58737,41613:58738,41614:58739,41615:58740,41616:58741,41617:58742,41618:58743,41619:58744,41620:58745,41621:58746,41622:58747,41623:58748,41624:58749,41625:58750,41626:58751,41627:58752,41628:58753,41629:58754,41630:58755,41631:58756,41632:58757,41633:8560,41634:8561,41635:8562,41636:8563,41637:8564,41638:8565,41639:8566,41640:8567,41641:8568,41642:8569,41643:59238,41644:59239,41645:59240,41646:59241,41647:59242,41648:59243,41649:9352,41650:9353,41651:9354,41652:9355,41653:9356,41654:9357,41655:9358,41656:9359,41657:9360,41658:9361,41659:9362,41660:9363,41661:9364,41662:9365,41663:9366,41664:9367,41665:9368,41666:9369,41667:9370,41668:9371,41669:9332,41670:9333,41671:9334,41672:9335,41673:9336,41674:9337,41675:9338,41676:9339,41677:9340,41678:9341,41679:9342,41680:9343,41681:9344,41682:9345,41683:9346,41684:9347,41685:9348,41686:9349,41687:9350,41688:9351,41689:9312,41690:9313,41691:9314,41692:9315,41693:9316,41694:9317,41695:9318,41696:9319,41697:9320,41698:9321,41699:8364,41700:59245,41701:12832,41702:12833,41703:12834,41704:12835,41705:12836,41706:12837,41707:12838,41708:12839,41709:12840,41710:12841,41711:59246,41712:59247,41713:8544,41714:8545,41715:8546,41716:8547,41717:8548,41718:8549,41719:8550,41720:8551,41721:8552,41722:8553,41723:8554,41724:8555,41725:59248,41726:59249,41792:58758,41793:58759,41794:58760,41795:58761,41796:58762,41797:58763,41798:58764,41799:58765,41800:58766,41801:58767,41802:58768,41803:58769,41804:58770,41805:58771,41806:58772,41807:58773,41808:58774,41809:58775,41810:58776,41811:58777,41812:58778,41813:58779,41814:58780,41815:58781,41816:58782,41817:58783,41818:58784,41819:58785,41820:58786,41821:58787,41822:58788,41823:58789,41824:58790,41825:58791,41826:58792,41827:58793,41828:58794,41829:58795,41830:58796,41831:58797,41832:58798,41833:58799,41834:58800,41835:58801,41836:58802,41837:58803,41838:58804,41839:58805,41840:58806,41841:58807,41842:58808,41843:58809,41844:58810,41845:58811,41846:58812,41847:58813,41848:58814,41849:58815,41850:58816,41851:58817,41852:58818,41853:58819,41854:58820,41856:58821,41857:58822,41858:58823,41859:58824,41860:58825,41861:58826,41862:58827,41863:58828,41864:58829,41865:58830,41866:58831,41867:58832,41868:58833,41869:58834,41870:58835,41871:58836,41872:58837,41873:58838,41874:58839,41875:58840,41876:58841,41877:58842,41878:58843,41879:58844,41880:58845,41881:58846,41882:58847,41883:58848,41884:58849,41885:58850,41886:58851,41887:58852,41888:58853,41889:65281,41890:65282,41891:65283,41892:65509,41893:65285,41894:65286,41895:65287,41896:65288,41897:65289,41898:65290,41899:65291,41900:65292,41901:65293,41902:65294,41903:65295,41904:65296,41905:65297,41906:65298,41907:65299,41908:65300,41909:65301,41910:65302,41911:65303,41912:65304,41913:65305,41914:65306,41915:65307,41916:65308,41917:65309,41918:65310,41919:65311,41920:65312,41921:65313,41922:65314,41923:65315,41924:65316,41925:65317,41926:65318,41927:65319,41928:65320,41929:65321,41930:65322,41931:65323,41932:65324,41933:65325,41934:65326,41935:65327,41936:65328,41937:65329,41938:65330,41939:65331,41940:65332,41941:65333,41942:65334,41943:65335,41944:65336,41945:65337,41946:65338,41947:65339,41948:65340,41949:65341,41950:65342,41951:65343,41952:65344,41953:65345,41954:65346,41955:65347,41956:65348,41957:65349,41958:65350,41959:65351,41960:65352,41961:65353,41962:65354,41963:65355,41964:65356,41965:65357,41966:65358,41967:65359,41968:65360,41969:65361,41970:65362,41971:65363,41972:65364,41973:65365,41974:65366,41975:65367,41976:65368,41977:65369,41978:65370,41979:65371,41980:65372,41981:65373,41982:65507,42048:58854,42049:58855,42050:58856,42051:58857,42052:58858,42053:58859,42054:58860,42055:58861,42056:58862,42057:58863,42058:58864,42059:58865,42060:58866,42061:58867,42062:58868,42063:58869,42064:58870,42065:58871,42066:58872,42067:58873,42068:58874,42069:58875,42070:58876,42071:58877,42072:58878,42073:58879,42074:58880,42075:58881,42076:58882,42077:58883,42078:58884,42079:58885,42080:58886,42081:58887,42082:58888,42083:58889,42084:58890,42085:58891,42086:58892,42087:58893,42088:58894,42089:58895,42090:58896,42091:58897,42092:58898,42093:58899,42094:58900,42095:58901,42096:58902,42097:58903,42098:58904,42099:58905,42100:58906,42101:58907,42102:58908,42103:58909,42104:58910,42105:58911,42106:58912,42107:58913,42108:58914,42109:58915,42110:58916,42112:58917,42113:58918,42114:58919,42115:58920,42116:58921,42117:58922,42118:58923,42119:58924,42120:58925,42121:58926,42122:58927,42123:58928,42124:58929,42125:58930,42126:58931,42127:58932,42128:58933,42129:58934,42130:58935,42131:58936,42132:58937,42133:58938,42134:58939,42135:58940,42136:58941,42137:58942,42138:58943,42139:58944,42140:58945,42141:58946,42142:58947,42143:58948,42144:58949,42145:12353,42146:12354,42147:12355,42148:12356,42149:12357,42150:12358,42151:12359,42152:12360,42153:12361,42154:12362,42155:12363,42156:12364,42157:12365,42158:12366,42159:12367,42160:12368,42161:12369,42162:12370,42163:12371,42164:12372,42165:12373,42166:12374,42167:12375,42168:12376,42169:12377,42170:12378,42171:12379,42172:12380,42173:12381,42174:12382,42175:12383,42176:12384,42177:12385,42178:12386,42179:12387,42180:12388,42181:12389,42182:12390,42183:12391,42184:12392,42185:12393,42186:12394,42187:12395,42188:12396,42189:12397,42190:12398,42191:12399,42192:12400,42193:12401,42194:12402,42195:12403,42196:12404,42197:12405,42198:12406,42199:12407,42200:12408,42201:12409,42202:12410,42203:12411,42204:12412,42205:12413,42206:12414,42207:12415,42208:12416,42209:12417,42210:12418,42211:12419,42212:12420,42213:12421,42214:12422,42215:12423,42216:12424,42217:12425,42218:12426,42219:12427,42220:12428,42221:12429,42222:12430,42223:12431,42224:12432,42225:12433,42226:12434,42227:12435,42228:59250,42229:59251,42230:59252,42231:59253,42232:59254,42233:59255,42234:59256,42235:59257,42236:59258,42237:59259,42238:59260,42304:58950,42305:58951,42306:58952,42307:58953,42308:58954,42309:58955,42310:58956,42311:58957,42312:58958,42313:58959,42314:58960,42315:58961,42316:58962,42317:58963,42318:58964,42319:58965,42320:58966,42321:58967,42322:58968,42323:58969,42324:58970,42325:58971,42326:58972,42327:58973,42328:58974,42329:58975,42330:58976,42331:58977,42332:58978,42333:58979,42334:58980,42335:58981,42336:58982,42337:58983,42338:58984,42339:58985,42340:58986,42341:58987,42342:58988,42343:58989,42344:58990,42345:58991,42346:58992,42347:58993,42348:58994,42349:58995,42350:58996,42351:58997,42352:58998,42353:58999,42354:59000,42355:59001,42356:59002,42357:59003,42358:59004,42359:59005,42360:59006,42361:59007,42362:59008,42363:59009,42364:59010,42365:59011,42366:59012,42368:59013,42369:59014,42370:59015,42371:59016,42372:59017,42373:59018,42374:59019,42375:59020,42376:59021,42377:59022,42378:59023,42379:59024,42380:59025,42381:59026,42382:59027,42383:59028,42384:59029,42385:59030,42386:59031,42387:59032,42388:59033,42389:59034,42390:59035,42391:59036,42392:59037,42393:59038,42394:59039,42395:59040,42396:59041,42397:59042,42398:59043,42399:59044,42400:59045,42401:12449,42402:12450,42403:12451,42404:12452,42405:12453,42406:12454,42407:12455,42408:12456,42409:12457,42410:12458,42411:12459,42412:12460,42413:12461,42414:12462,42415:12463,42416:12464,42417:12465,42418:12466,42419:12467,42420:12468,42421:12469,42422:12470,42423:12471,42424:12472,42425:12473,42426:12474,42427:12475,42428:12476,42429:12477,42430:12478,42431:12479,42432:12480,42433:12481,42434:12482,42435:12483,42436:12484,42437:12485,42438:12486,42439:12487,42440:12488,42441:12489,42442:12490,42443:12491,42444:12492,42445:12493,42446:12494,42447:12495,42448:12496,42449:12497,42450:12498,42451:12499,42452:12500,42453:12501,42454:12502,42455:12503,42456:12504,42457:12505,42458:12506,42459:12507,42460:12508,42461:12509,42462:12510,42463:12511,42464:12512,42465:12513,42466:12514,42467:12515,42468:12516,42469:12517,42470:12518,42471:12519,42472:12520,42473:12521,42474:12522,42475:12523,42476:12524,42477:12525,42478:12526,42479:12527,42480:12528,42481:12529,42482:12530,42483:12531,42484:12532,42485:12533,42486:12534,42487:59261,42488:59262,42489:59263,42490:59264,42491:59265,42492:59266,42493:59267,42494:59268,42560:59046,42561:59047,42562:59048,42563:59049,42564:59050,42565:59051,42566:59052,42567:59053,42568:59054,42569:59055,42570:59056,42571:59057,42572:59058,42573:59059,42574:59060,42575:59061,42576:59062,42577:59063,42578:59064,42579:59065,42580:59066,42581:59067,42582:59068,42583:59069,42584:59070,42585:59071,42586:59072,42587:59073,42588:59074,42589:59075,42590:59076,42591:59077,42592:59078,42593:59079,42594:59080,42595:59081,42596:59082,42597:59083,42598:59084,42599:59085,42600:59086,42601:59087,42602:59088,42603:59089,42604:59090,42605:59091,42606:59092,42607:59093,42608:59094,42609:59095,42610:59096,42611:59097,42612:59098,42613:59099,42614:59100,42615:59101,42616:59102,42617:59103,42618:59104,42619:59105,42620:59106,42621:59107,42622:59108,42624:59109,42625:59110,42626:59111,42627:59112,42628:59113,42629:59114,42630:59115,42631:59116,42632:59117,42633:59118,42634:59119,42635:59120,42636:59121,42637:59122,42638:59123,42639:59124,42640:59125,42641:59126,42642:59127,42643:59128,42644:59129,42645:59130,42646:59131,42647:59132,42648:59133,42649:59134,42650:59135,42651:59136,42652:59137,42653:59138,42654:59139,42655:59140,42656:59141,42657:913,42658:914,42659:915,42660:916,42661:917,42662:918,42663:919,42664:920,42665:921,42666:922,42667:923,42668:924,42669:925,42670:926,42671:927,42672:928,42673:929,42674:931,42675:932,42676:933,42677:934,42678:935,42679:936,42680:937,42681:59269,42682:59270,42683:59271,42684:59272,42685:59273,42686:59274,42687:59275,42688:59276,42689:945,42690:946,42691:947,42692:948,42693:949,42694:950,42695:951,42696:952,42697:953,42698:954,42699:955,42700:956,42701:957,42702:958,42703:959,42704:960,42705:961,42706:963,42707:964,42708:965,42709:966,42710:967,42711:968,42712:969,42713:59277,42714:59278,42715:59279,42716:59280,42717:59281,42718:59282,42719:59283,42720:65077,42721:65078,42722:65081,42723:65082,42724:65087,42725:65088,42726:65085,42727:65086,42728:65089,42729:65090,42730:65091,42731:65092,42732:59284,42733:59285,42734:65083,42735:65084,42736:65079,42737:65080,42738:65073,42739:59286,42740:65075,42741:65076,42742:59287,42743:59288,42744:59289,42745:59290,42746:59291,42747:59292,42748:59293,42749:59294,42750:59295,42816:59142,42817:59143,42818:59144,42819:59145,42820:59146,42821:59147,42822:59148,42823:59149,42824:59150,42825:59151,42826:59152,42827:59153,42828:59154,42829:59155,42830:59156,42831:59157,42832:59158,42833:59159,42834:59160,42835:59161,42836:59162,42837:59163,42838:59164,42839:59165,42840:59166,42841:59167,42842:59168,42843:59169,42844:59170,42845:59171,42846:59172,42847:59173,42848:59174,42849:59175,42850:59176,42851:59177,42852:59178,42853:59179,42854:59180,42855:59181,42856:59182,42857:59183,42858:59184,42859:59185,42860:59186,42861:59187,42862:59188,42863:59189,42864:59190,42865:59191,42866:59192,42867:59193,42868:59194,42869:59195,42870:59196,42871:59197,42872:59198,42873:59199,42874:59200,42875:59201,42876:59202,42877:59203,42878:59204,42880:59205,42881:59206,42882:59207,42883:59208,42884:59209,42885:59210,42886:59211,42887:59212,42888:59213,42889:59214,42890:59215,42891:59216,42892:59217,42893:59218,42894:59219,42895:59220,42896:59221,42897:59222,42898:59223,42899:59224,42900:59225,42901:59226,42902:59227,42903:59228,42904:59229,42905:59230,42906:59231,42907:59232,42908:59233,42909:59234,42910:59235,42911:59236,42912:59237,42913:1040,42914:1041,42915:1042,42916:1043,42917:1044,42918:1045,42919:1025,42920:1046,42921:1047,42922:1048,42923:1049,42924:1050,42925:1051,42926:1052,42927:1053,42928:1054,42929:1055,42930:1056,42931:1057,42932:1058,42933:1059,42934:1060,42935:1061,42936:1062,42937:1063,42938:1064,42939:1065,42940:1066,42941:1067,42942:1068,42943:1069,42944:1070,42945:1071,42946:59296,42947:59297,42948:59298,42949:59299,42950:59300,42951:59301,42952:59302,42953:59303,42954:59304,42955:59305,42956:59306,42957:59307,42958:59308,42959:59309,42960:59310,42961:1072,42962:1073,42963:1074,42964:1075,42965:1076,42966:1077,42967:1105,42968:1078,42969:1079,42970:1080,42971:1081,42972:1082,42973:1083,42974:1084,42975:1085,42976:1086,42977:1087,42978:1088,42979:1089,42980:1090,42981:1091,42982:1092,42983:1093,42984:1094,42985:1095,42986:1096,42987:1097,42988:1098,42989:1099,42990:1100,42991:1101,42992:1102,42993:1103,42994:59311,42995:59312,42996:59313,42997:59314,42998:59315,42999:59316,43000:59317,43001:59318,43002:59319,43003:59320,43004:59321,43005:59322,43006:59323,43072:714,43073:715,43074:729,43075:8211,43076:8213,43077:8229,43078:8245,43079:8453,43080:8457,43081:8598,43082:8599,43083:8600,43084:8601,43085:8725,43086:8735,43087:8739,43088:8786,43089:8806,43090:8807,43091:8895,43092:9552,43093:9553,43094:9554,43095:9555,43096:9556,43097:9557,43098:9558,43099:9559,43100:9560,43101:9561,43102:9562,43103:9563,43104:9564,43105:9565,43106:9566,43107:9567,43108:9568,43109:9569,43110:9570,43111:9571,43112:9572,43113:9573,43114:9574,43115:9575,43116:9576,43117:9577,43118:9578,43119:9579,43120:9580,43121:9581,43122:9582,43123:9583,43124:9584,43125:9585,43126:9586,43127:9587,43128:9601,43129:9602,43130:9603,43131:9604,43132:9605,43133:9606,43134:9607,43136:9608,43137:9609,43138:9610,43139:9611,43140:9612,43141:9613,43142:9614,43143:9615,43144:9619,43145:9620,43146:9621,43147:9660,43148:9661,43149:9698,43150:9699,43151:9700,43152:9701,43153:9737,43154:8853,43155:12306,43156:12317,43157:12318,43158:59324,43159:59325,43160:59326,43161:59327,43162:59328,43163:59329,43164:59330,43165:59331,43166:59332,43167:59333,43168:59334,43169:257,43170:225,43171:462,43172:224,43173:275,43174:233,43175:283,43176:232,43177:299,43178:237,43179:464,43180:236,43181:333,43182:243,43183:466,43184:242,43185:363,43186:250,43187:468,43188:249,43189:470,43190:472,43191:474,43192:476,43193:252,43194:234,43195:593,43196:59335,43197:324,43198:328,43199:505,43200:609,43201:59337,43202:59338,43203:59339,43204:59340,43205:12549,43206:12550,43207:12551,43208:12552,43209:12553,43210:12554,43211:12555,43212:12556,43213:12557,43214:12558,43215:12559,43216:12560,43217:12561,43218:12562,43219:12563,43220:12564,43221:12565,43222:12566,43223:12567,43224:12568,43225:12569,43226:12570,43227:12571,43228:12572,43229:12573,43230:12574,43231:12575,43232:12576,43233:12577,43234:12578,43235:12579,43236:12580,43237:12581,43238:12582,43239:12583,43240:12584,43241:12585,43242:59341,43243:59342,43244:59343,43245:59344,43246:59345,43247:59346,43248:59347,43249:59348,43250:59349,43251:59350,43252:59351,43253:59352,43254:59353,43255:59354,43256:59355,43257:59356,43258:59357,43259:59358,43260:59359,43261:59360,43262:59361,43328:12321,43329:12322,43330:12323,43331:12324,43332:12325,43333:12326,43334:12327,43335:12328,43336:12329,43337:12963,43338:13198,43339:13199,43340:13212,43341:13213,43342:13214,43343:13217,43344:13252,43345:13262,43346:13265,43347:13266,43348:13269,43349:65072,43350:65506,43351:65508,43352:59362,43353:8481,43354:12849,43355:59363,43356:8208,43357:59364,43358:59365,43359:59366,43360:12540,43361:12443,43362:12444,43363:12541,43364:12542,43365:12294,43366:12445,43367:12446,43368:65097,43369:65098,43370:65099,43371:65100,43372:65101,43373:65102,43374:65103,43375:65104,43376:65105,43377:65106,43378:65108,43379:65109,43380:65110,43381:65111,43382:65113,43383:65114,43384:65115,43385:65116,43386:65117,43387:65118,43388:65119,43389:65120,43390:65121,43392:65122,43393:65123,43394:65124,43395:65125,43396:65126,43397:65128,43398:65129,43399:65130,43400:65131,43401:12350,43402:12272,43403:12273,43404:12274,43405:12275,43406:12276,43407:12277,43408:12278,43409:12279,43410:12280,43411:12281,43412:12282,43413:12283,43414:12295,43415:59380,43416:59381,43417:59382,43418:59383,43419:59384,43420:59385,43421:59386,43422:59387,43423:59388,43424:59389,43425:59390,43426:59391,43427:59392,43428:9472,43429:9473,43430:9474,43431:9475,43432:9476,43433:9477,43434:9478,43435:9479,43436:9480,43437:9481,43438:9482,43439:9483,43440:9484,43441:9485,43442:9486,43443:9487,43444:9488,43445:9489,43446:9490,43447:9491,43448:9492,43449:9493,43450:9494,43451:9495,43452:9496,43453:9497,43454:9498,43455:9499,43456:9500,43457:9501,43458:9502,43459:9503,43460:9504,43461:9505,43462:9506,43463:9507,43464:9508,43465:9509,43466:9510,43467:9511,43468:9512,43469:9513,43470:9514,43471:9515,43472:9516,43473:9517,43474:9518,43475:9519,43476:9520,43477:9521,43478:9522,43479:9523,43480:9524,43481:9525,43482:9526,43483:9527,43484:9528,43485:9529,43486:9530,43487:9531,43488:9532,43489:9533,43490:9534,43491:9535,43492:9536,43493:9537,43494:9538,43495:9539,43496:9540,43497:9541,43498:9542,43499:9543,43500:9544,43501:9545,43502:9546,43503:9547,43504:59393,43505:59394,43506:59395,43507:59396,43508:59397,43509:59398,43510:59399,43511:59400,43512:59401,43513:59402,43514:59403,43515:59404,43516:59405,43517:59406,43518:59407,43584:29404,43585:29405,43586:29407,43587:29410,43588:29411,43589:29412,43590:29413,43591:29414,43592:29415,43593:29418,43594:29419,43595:29429,43596:29430,43597:29433,43598:29437,43599:29438,43600:29439,43601:29440,43602:29442,43603:29444,43604:29445,43605:29446,43606:29447,43607:29448,43608:29449,43609:29451,43610:29452,43611:29453,43612:29455,43613:29456,43614:29457,43615:29458,43616:29460,43617:29464,43618:29465,43619:29466,43620:29471,43621:29472,43622:29475,43623:29476,43624:29478,43625:29479,43626:29480,43627:29485,43628:29487,43629:29488,43630:29490,43631:29491,43632:29493,43633:29494,43634:29498,43635:29499,43636:29500,43637:29501,43638:29504,43639:29505,43640:29506,43641:29507,43642:29508,43643:29509,43644:29510,43645:29511,43646:29512,43648:29513,43649:29514,43650:29515,43651:29516,43652:29518,43653:29519,43654:29521,43655:29523,43656:29524,43657:29525,43658:29526,43659:29528,43660:29529,43661:29530,43662:29531,43663:29532,43664:29533,43665:29534,43666:29535,43667:29537,43668:29538,43669:29539,43670:29540,43671:29541,43672:29542,43673:29543,43674:29544,43675:29545,43676:29546,43677:29547,43678:29550,43679:29552,43680:29553,43681:57344,43682:57345,43683:57346,43684:57347,43685:57348,43686:57349,43687:57350,43688:57351,43689:57352,43690:57353,43691:57354,43692:57355,43693:57356,43694:57357,43695:57358,43696:57359,43697:57360,43698:57361,43699:57362,43700:57363,43701:57364,43702:57365,43703:57366,43704:57367,43705:57368,43706:57369,43707:57370,43708:57371,43709:57372,43710:57373,43711:57374,43712:57375,43713:57376,43714:57377,43715:57378,43716:57379,43717:57380,43718:57381,43719:57382,43720:57383,43721:57384,43722:57385,43723:57386,43724:57387,43725:57388,43726:57389,43727:57390,43728:57391,43729:57392,43730:57393,43731:57394,43732:57395,43733:57396,43734:57397,43735:57398,43736:57399,43737:57400,43738:57401,43739:57402,43740:57403,43741:57404,43742:57405,43743:57406,43744:57407,43745:57408,43746:57409,43747:57410,43748:57411,43749:57412,43750:57413,43751:57414,43752:57415,43753:57416,43754:57417,43755:57418,43756:57419,43757:57420,43758:57421,43759:57422,43760:57423,43761:57424,43762:57425,43763:57426,43764:57427,43765:57428,43766:57429,43767:57430,43768:57431,43769:57432,43770:57433,43771:57434,43772:57435,43773:57436,43774:57437,43840:29554,43841:29555,43842:29556,43843:29557,43844:29558,43845:29559,43846:29560,43847:29561,43848:29562,43849:29563,43850:29564,43851:29565,43852:29567,43853:29568,43854:29569,43855:29570,43856:29571,43857:29573,43858:29574,43859:29576,43860:29578,43861:29580,43862:29581,43863:29583,43864:29584,43865:29586,43866:29587,43867:29588,43868:29589,43869:29591,43870:29592,43871:29593,43872:29594,43873:29596,43874:29597,43875:29598,43876:29600,43877:29601,43878:29603,43879:29604,43880:29605,43881:29606,43882:29607,43883:29608,43884:29610,43885:29612,43886:29613,43887:29617,43888:29620,43889:29621,43890:29622,43891:29624,43892:29625,43893:29628,43894:29629,43895:29630,43896:29631,43897:29633,43898:29635,43899:29636,43900:29637,43901:29638,43902:29639,43904:29643,43905:29644,43906:29646,43907:29650,43908:29651,43909:29652,43910:29653,43911:29654,43912:29655,43913:29656,43914:29658,43915:29659,43916:29660,43917:29661,43918:29663,43919:29665,43920:29666,43921:29667,43922:29668,43923:29670,43924:29672,43925:29674,43926:29675,43927:29676,43928:29678,43929:29679,43930:29680,43931:29681,43932:29683,43933:29684,43934:29685,43935:29686,43936:29687,43937:57438,43938:57439,43939:57440,43940:57441,43941:57442,43942:57443,43943:57444,43944:57445,43945:57446,43946:57447,43947:57448,43948:57449,43949:57450,43950:57451,43951:57452,43952:57453,43953:57454,43954:57455,43955:57456,43956:57457,43957:57458,43958:57459,43959:57460,43960:57461,43961:57462,43962:57463,43963:57464,43964:57465,43965:57466,43966:57467,43967:57468,43968:57469,43969:57470,43970:57471,43971:57472,43972:57473,43973:57474,43974:57475,43975:57476,43976:57477,43977:57478,43978:57479,43979:57480,43980:57481,43981:57482,43982:57483,43983:57484,43984:57485,43985:57486,43986:57487,43987:57488,43988:57489,43989:57490,43990:57491,43991:57492,43992:57493,43993:57494,43994:57495,43995:57496,43996:57497,43997:57498,43998:57499,43999:57500,44000:57501,44001:57502,44002:57503,44003:57504,44004:57505,44005:57506,44006:57507,44007:57508,44008:57509,44009:57510,44010:57511,44011:57512,44012:57513,44013:57514,44014:57515,44015:57516,44016:57517,44017:57518,44018:57519,44019:57520,44020:57521,44021:57522,44022:57523,44023:57524,44024:57525,44025:57526,44026:57527,44027:57528,44028:57529,44029:57530,44030:57531,44096:29688,44097:29689,44098:29690,44099:29691,44100:29692,44101:29693,44102:29694,44103:29695,44104:29696,44105:29697,44106:29698,44107:29700,44108:29703,44109:29704,44110:29707,44111:29708,44112:29709,44113:29710,44114:29713,44115:29714,44116:29715,44117:29716,44118:29717,44119:29718,44120:29719,44121:29720,44122:29721,44123:29724,44124:29725,44125:29726,44126:29727,44127:29728,44128:29729,44129:29731,44130:29732,44131:29735,44132:29737,44133:29739,44134:29741,44135:29743,44136:29745,44137:29746,44138:29751,44139:29752,44140:29753,44141:29754,44142:29755,44143:29757,44144:29758,44145:29759,44146:29760,44147:29762,44148:29763,44149:29764,44150:29765,44151:29766,44152:29767,44153:29768,44154:29769,44155:29770,44156:29771,44157:29772,44158:29773,44160:29774,44161:29775,44162:29776,44163:29777,44164:29778,44165:29779,44166:29780,44167:29782,44168:29784,44169:29789,44170:29792,44171:29793,44172:29794,44173:29795,44174:29796,44175:29797,44176:29798,44177:29799,44178:29800,44179:29801,44180:29802,44181:29803,44182:29804,44183:29806,44184:29807,44185:29809,44186:29810,44187:29811,44188:29812,44189:29813,44190:29816,44191:29817,44192:29818,44193:57532,44194:57533,44195:57534,44196:57535,44197:57536,44198:57537,44199:57538,44200:57539,44201:57540,44202:57541,44203:57542,44204:57543,44205:57544,44206:57545,44207:57546,44208:57547,44209:57548,44210:57549,44211:57550,44212:57551,44213:57552,44214:57553,44215:57554,44216:57555,44217:57556,44218:57557,44219:57558,44220:57559,44221:57560,44222:57561,44223:57562,44224:57563,44225:57564,44226:57565,44227:57566,44228:57567,44229:57568,44230:57569,44231:57570,44232:57571,44233:57572,44234:57573,44235:57574,44236:57575,44237:57576,44238:57577,44239:57578,44240:57579,44241:57580,44242:57581,44243:57582,44244:57583,44245:57584,44246:57585,44247:57586,44248:57587,44249:57588,44250:57589,44251:57590,44252:57591,44253:57592,44254:57593,44255:57594,44256:57595,44257:57596,44258:57597,44259:57598,44260:57599,44261:57600,44262:57601,44263:57602,44264:57603,44265:57604,44266:57605,44267:57606,44268:57607,44269:57608,44270:57609,44271:57610,44272:57611,44273:57612,44274:57613,44275:57614,44276:57615,44277:57616,44278:57617,44279:57618,44280:57619,44281:57620,44282:57621,44283:57622,44284:57623,44285:57624,44286:57625,44352:29819,44353:29820,44354:29821,44355:29823,44356:29826,44357:29828,44358:29829,44359:29830,44360:29832,44361:29833,44362:29834,44363:29836,44364:29837,44365:29839,44366:29841,44367:29842,44368:29843,44369:29844,44370:29845,44371:29846,44372:29847,44373:29848,44374:29849,44375:29850,44376:29851,44377:29853,44378:29855,44379:29856,44380:29857,44381:29858,44382:29859,44383:29860,44384:29861,44385:29862,44386:29866,44387:29867,44388:29868,44389:29869,44390:29870,44391:29871,44392:29872,44393:29873,44394:29874,44395:29875,44396:29876,44397:29877,44398:29878,44399:29879,44400:29880,44401:29881,44402:29883,44403:29884,44404:29885,44405:29886,44406:29887,44407:29888,44408:29889,44409:29890,44410:29891,44411:29892,44412:29893,44413:29894,44414:29895,44416:29896,44417:29897,44418:29898,44419:29899,44420:29900,44421:29901,44422:29902,44423:29903,44424:29904,44425:29905,44426:29907,44427:29908,44428:29909,44429:29910,44430:29911,44431:29912,44432:29913,44433:29914,44434:29915,44435:29917,44436:29919,44437:29921,44438:29925,44439:29927,44440:29928,44441:29929,44442:29930,44443:29931,44444:29932,44445:29933,44446:29936,44447:29937,44448:29938,44449:57626,44450:57627,44451:57628,44452:57629,44453:57630,44454:57631,44455:57632,44456:57633,44457:57634,44458:57635,44459:57636,44460:57637,44461:57638,44462:57639,44463:57640,44464:57641,44465:57642,44466:57643,44467:57644,44468:57645,44469:57646,44470:57647,44471:57648,44472:57649,44473:57650,44474:57651,44475:57652,44476:57653,44477:57654,44478:57655,44479:57656,44480:57657,44481:57658,44482:57659,44483:57660,44484:57661,44485:57662,44486:57663,44487:57664,44488:57665,44489:57666,44490:57667,44491:57668,44492:57669,44493:57670,44494:57671,44495:57672,44496:57673,44497:57674,44498:57675,44499:57676,44500:57677,44501:57678,44502:57679,44503:57680,44504:57681,44505:57682,44506:57683,44507:57684,44508:57685,44509:57686,44510:57687,44511:57688,44512:57689,44513:57690,44514:57691,44515:57692,44516:57693,44517:57694,44518:57695,44519:57696,44520:57697,44521:57698,44522:57699,44523:57700,44524:57701,44525:57702,44526:57703,44527:57704,44528:57705,44529:57706,44530:57707,44531:57708,44532:57709,44533:57710,44534:57711,44535:57712,44536:57713,44537:57714,44538:57715,44539:57716,44540:57717,44541:57718,44542:57719,44608:29939,44609:29941,44610:29944,44611:29945,44612:29946,44613:29947,44614:29948,44615:29949,44616:29950,44617:29952,44618:29953,44619:29954,44620:29955,44621:29957,44622:29958,44623:29959,44624:29960,44625:29961,44626:29962,44627:29963,44628:29964,44629:29966,44630:29968,44631:29970,44632:29972,44633:29973,44634:29974,44635:29975,44636:29979,44637:29981,44638:29982,44639:29984,44640:29985,44641:29986,44642:29987,44643:29988,44644:29990,44645:29991,44646:29994,44647:29998,44648:30004,44649:30006,44650:30009,44651:30012,44652:30013,44653:30015,44654:30017,44655:30018,44656:30019,44657:30020,44658:30022,44659:30023,44660:30025,44661:30026,44662:30029,44663:30032,44664:30033,44665:30034,44666:30035,44667:30037,44668:30038,44669:30039,44670:30040,44672:30045,44673:30046,44674:30047,44675:30048,44676:30049,44677:30050,44678:30051,44679:30052,44680:30055,44681:30056,44682:30057,44683:30059,44684:30060,44685:30061,44686:30062,44687:30063,44688:30064,44689:30065,44690:30067,44691:30069,44692:30070,44693:30071,44694:30074,44695:30075,44696:30076,44697:30077,44698:30078,44699:30080,44700:30081,44701:30082,44702:30084,44703:30085,44704:30087,44705:57720,44706:57721,44707:57722,44708:57723,44709:57724,44710:57725,44711:57726,44712:57727,44713:57728,44714:57729,44715:57730,44716:57731,44717:57732,44718:57733,44719:57734,44720:57735,44721:57736,44722:57737,44723:57738,44724:57739,44725:57740,44726:57741,44727:57742,44728:57743,44729:57744,44730:57745,44731:57746,44732:57747,44733:57748,44734:57749,44735:57750,44736:57751,44737:57752,44738:57753,44739:57754,44740:57755,44741:57756,44742:57757,44743:57758,44744:57759,44745:57760,44746:57761,44747:57762,44748:57763,44749:57764,44750:57765,44751:57766,44752:57767,44753:57768,44754:57769,44755:57770,44756:57771,44757:57772,44758:57773,44759:57774,44760:57775,44761:57776,44762:57777,44763:57778,44764:57779,44765:57780,44766:57781,44767:57782,44768:57783,44769:57784,44770:57785,44771:57786,44772:57787,44773:57788,44774:57789,44775:57790,44776:57791,44777:57792,44778:57793,44779:57794,44780:57795,44781:57796,44782:57797,44783:57798,44784:57799,44785:57800,44786:57801,44787:57802,44788:57803,44789:57804,44790:57805,44791:57806,44792:57807,44793:57808,44794:57809,44795:57810,44796:57811,44797:57812,44798:57813,44864:30088,44865:30089,44866:30090,44867:30092,44868:30093,44869:30094,44870:30096,44871:30099,44872:30101,44873:30104,44874:30107,44875:30108,44876:30110,44877:30114,44878:30118,44879:30119,44880:30120,44881:30121,44882:30122,44883:30125,44884:30134,44885:30135,44886:30138,44887:30139,44888:30143,44889:30144,44890:30145,44891:30150,44892:30155,44893:30156,44894:30158,44895:30159,44896:30160,44897:30161,44898:30163,44899:30167,44900:30169,44901:30170,44902:30172,44903:30173,44904:30175,44905:30176,44906:30177,44907:30181,44908:30185,44909:30188,44910:30189,44911:30190,44912:30191,44913:30194,44914:30195,44915:30197,44916:30198,44917:30199,44918:30200,44919:30202,44920:30203,44921:30205,44922:30206,44923:30210,44924:30212,44925:30214,44926:30215,44928:30216,44929:30217,44930:30219,44931:30221,44932:30222,44933:30223,44934:30225,44935:30226,44936:30227,44937:30228,44938:30230,44939:30234,44940:30236,44941:30237,44942:30238,44943:30241,44944:30243,44945:30247,44946:30248,44947:30252,44948:30254,44949:30255,44950:30257,44951:30258,44952:30262,44953:30263,44954:30265,44955:30266,44956:30267,44957:30269,44958:30273,44959:30274,44960:30276,44961:57814,44962:57815,44963:57816,44964:57817,44965:57818,44966:57819,44967:57820,44968:57821,44969:57822,44970:57823,44971:57824,44972:57825,44973:57826,44974:57827,44975:57828,44976:57829,44977:57830,44978:57831,44979:57832,44980:57833,44981:57834,44982:57835,44983:57836,44984:57837,44985:57838,44986:57839,44987:57840,44988:57841,44989:57842,44990:57843,44991:57844,44992:57845,44993:57846,44994:57847,44995:57848,44996:57849,44997:57850,44998:57851,44999:57852,45000:57853,45001:57854,45002:57855,45003:57856,45004:57857,45005:57858,45006:57859,45007:57860,45008:57861,45009:57862,45010:57863,45011:57864,45012:57865,45013:57866,45014:57867,45015:57868,45016:57869,45017:57870,45018:57871,45019:57872,45020:57873,45021:57874,45022:57875,45023:57876,45024:57877,45025:57878,45026:57879,45027:57880,45028:57881,45029:57882,45030:57883,45031:57884,45032:57885,45033:57886,45034:57887,45035:57888,45036:57889,45037:57890,45038:57891,45039:57892,45040:57893,45041:57894,45042:57895,45043:57896,45044:57897,45045:57898,45046:57899,45047:57900,45048:57901,45049:57902,45050:57903,45051:57904,45052:57905,45053:57906,45054:57907,45120:30277,45121:30278,45122:30279,45123:30280,45124:30281,45125:30282,45126:30283,45127:30286,45128:30287,45129:30288,45130:30289,45131:30290,45132:30291,45133:30293,45134:30295,45135:30296,45136:30297,45137:30298,45138:30299,45139:30301,45140:30303,45141:30304,45142:30305,45143:30306,45144:30308,45145:30309,45146:30310,45147:30311,45148:30312,45149:30313,45150:30314,45151:30316,45152:30317,45153:30318,45154:30320,45155:30321,45156:30322,45157:30323,45158:30324,45159:30325,45160:30326,45161:30327,45162:30329,45163:30330,45164:30332,45165:30335,45166:30336,45167:30337,45168:30339,45169:30341,45170:30345,45171:30346,45172:30348,45173:30349,45174:30351,45175:30352,45176:30354,45177:30356,45178:30357,45179:30359,45180:30360,45181:30362,45182:30363,45184:30364,45185:30365,45186:30366,45187:30367,45188:30368,45189:30369,45190:30370,45191:30371,45192:30373,45193:30374,45194:30375,45195:30376,45196:30377,45197:30378,45198:30379,45199:30380,45200:30381,45201:30383,45202:30384,45203:30387,45204:30389,45205:30390,45206:30391,45207:30392,45208:30393,45209:30394,45210:30395,45211:30396,45212:30397,45213:30398,45214:30400,45215:30401,45216:30403,45217:21834,45218:38463,45219:22467,45220:25384,45221:21710,45222:21769,45223:21696,45224:30353,45225:30284,45226:34108,45227:30702,45228:33406,45229:30861,45230:29233,45231:38552,45232:38797,45233:27688,45234:23433,45235:20474,45236:25353,45237:26263,45238:23736,45239:33018,45240:26696,45241:32942,45242:26114,45243:30414,45244:20985,45245:25942,45246:29100,45247:32753,45248:34948,45249:20658,45250:22885,45251:25034,45252:28595,45253:33453,45254:25420,45255:25170,45256:21485,45257:21543,45258:31494,45259:20843,45260:30116,45261:24052,45262:25300,45263:36299,45264:38774,45265:25226,45266:32793,45267:22365,45268:38712,45269:32610,45270:29240,45271:30333,45272:26575,45273:30334,45274:25670,45275:20336,45276:36133,45277:25308,45278:31255,45279:26001,45280:29677,45281:25644,45282:25203,45283:33324,45284:39041,45285:26495,45286:29256,45287:25198,45288:25292,45289:20276,45290:29923,45291:21322,45292:21150,45293:32458,45294:37030,45295:24110,45296:26758,45297:27036,45298:33152,45299:32465,45300:26834,45301:30917,45302:34444,45303:38225,45304:20621,45305:35876,45306:33502,45307:32990,45308:21253,45309:35090,45310:21093,45376:30404,45377:30407,45378:30409,45379:30411,45380:30412,45381:30419,45382:30421,45383:30425,45384:30426,45385:30428,45386:30429,45387:30430,45388:30432,45389:30433,45390:30434,45391:30435,45392:30436,45393:30438,45394:30439,45395:30440,45396:30441,45397:30442,45398:30443,45399:30444,45400:30445,45401:30448,45402:30451,45403:30453,45404:30454,45405:30455,45406:30458,45407:30459,45408:30461,45409:30463,45410:30464,45411:30466,45412:30467,45413:30469,45414:30470,45415:30474,45416:30476,45417:30478,45418:30479,45419:30480,45420:30481,45421:30482,45422:30483,45423:30484,45424:30485,45425:30486,45426:30487,45427:30488,45428:30491,45429:30492,45430:30493,45431:30494,45432:30497,45433:30499,45434:30500,45435:30501,45436:30503,45437:30506,45438:30507,45440:30508,45441:30510,45442:30512,45443:30513,45444:30514,45445:30515,45446:30516,45447:30521,45448:30523,45449:30525,45450:30526,45451:30527,45452:30530,45453:30532,45454:30533,45455:30534,45456:30536,45457:30537,45458:30538,45459:30539,45460:30540,45461:30541,45462:30542,45463:30543,45464:30546,45465:30547,45466:30548,45467:30549,45468:30550,45469:30551,45470:30552,45471:30553,45472:30556,45473:34180,45474:38649,45475:20445,45476:22561,45477:39281,45478:23453,45479:25265,45480:25253,45481:26292,45482:35961,45483:40077,45484:29190,45485:26479,45486:30865,45487:24754,45488:21329,45489:21271,45490:36744,45491:32972,45492:36125,45493:38049,45494:20493,45495:29384,45496:22791,45497:24811,45498:28953,45499:34987,45500:22868,45501:33519,45502:26412,45503:31528,45504:23849,45505:32503,45506:29997,45507:27893,45508:36454,45509:36856,45510:36924,45511:40763,45512:27604,45513:37145,45514:31508,45515:24444,45516:30887,45517:34006,45518:34109,45519:27605,45520:27609,45521:27606,45522:24065,45523:24199,45524:30201,45525:38381,45526:25949,45527:24330,45528:24517,45529:36767,45530:22721,45531:33218,45532:36991,45533:38491,45534:38829,45535:36793,45536:32534,45537:36140,45538:25153,45539:20415,45540:21464,45541:21342,45542:36776,45543:36777,45544:36779,45545:36941,45546:26631,45547:24426,45548:33176,45549:34920,45550:40150,45551:24971,45552:21035,45553:30250,45554:24428,45555:25996,45556:28626,45557:28392,45558:23486,45559:25672,45560:20853,45561:20912,45562:26564,45563:19993,45564:31177,45565:39292,45566:28851,45632:30557,45633:30558,45634:30559,45635:30560,45636:30564,45637:30567,45638:30569,45639:30570,45640:30573,45641:30574,45642:30575,45643:30576,45644:30577,45645:30578,45646:30579,45647:30580,45648:30581,45649:30582,45650:30583,45651:30584,45652:30586,45653:30587,45654:30588,45655:30593,45656:30594,45657:30595,45658:30598,45659:30599,45660:30600,45661:30601,45662:30602,45663:30603,45664:30607,45665:30608,45666:30611,45667:30612,45668:30613,45669:30614,45670:30615,45671:30616,45672:30617,45673:30618,45674:30619,45675:30620,45676:30621,45677:30622,45678:30625,45679:30627,45680:30628,45681:30630,45682:30632,45683:30635,45684:30637,45685:30638,45686:30639,45687:30641,45688:30642,45689:30644,45690:30646,45691:30647,45692:30648,45693:30649,45694:30650,45696:30652,45697:30654,45698:30656,45699:30657,45700:30658,45701:30659,45702:30660,45703:30661,45704:30662,45705:30663,45706:30664,45707:30665,45708:30666,45709:30667,45710:30668,45711:30670,45712:30671,45713:30672,45714:30673,45715:30674,45716:30675,45717:30676,45718:30677,45719:30678,45720:30680,45721:30681,45722:30682,45723:30685,45724:30686,45725:30687,45726:30688,45727:30689,45728:30692,45729:30149,45730:24182,45731:29627,45732:33760,45733:25773,45734:25320,45735:38069,45736:27874,45737:21338,45738:21187,45739:25615,45740:38082,45741:31636,45742:20271,45743:24091,45744:33334,45745:33046,45746:33162,45747:28196,45748:27850,45749:39539,45750:25429,45751:21340,45752:21754,45753:34917,45754:22496,45755:19981,45756:24067,45757:27493,45758:31807,45759:37096,45760:24598,45761:25830,45762:29468,45763:35009,45764:26448,45765:25165,45766:36130,45767:30572,45768:36393,45769:37319,45770:24425,45771:33756,45772:34081,45773:39184,45774:21442,45775:34453,45776:27531,45777:24813,45778:24808,45779:28799,45780:33485,45781:33329,45782:20179,45783:27815,45784:34255,45785:25805,45786:31961,45787:27133,45788:26361,45789:33609,45790:21397,45791:31574,45792:20391,45793:20876,45794:27979,45795:23618,45796:36461,45797:25554,45798:21449,45799:33580,45800:33590,45801:26597,45802:30900,45803:25661,45804:23519,45805:23700,45806:24046,45807:35815,45808:25286,45809:26612,45810:35962,45811:25600,45812:25530,45813:34633,45814:39307,45815:35863,45816:32544,45817:38130,45818:20135,45819:38416,45820:39076,45821:26124,45822:29462,45888:30694,45889:30696,45890:30698,45891:30703,45892:30704,45893:30705,45894:30706,45895:30708,45896:30709,45897:30711,45898:30713,45899:30714,45900:30715,45901:30716,45902:30723,45903:30724,45904:30725,45905:30726,45906:30727,45907:30728,45908:30730,45909:30731,45910:30734,45911:30735,45912:30736,45913:30739,45914:30741,45915:30745,45916:30747,45917:30750,45918:30752,45919:30753,45920:30754,45921:30756,45922:30760,45923:30762,45924:30763,45925:30766,45926:30767,45927:30769,45928:30770,45929:30771,45930:30773,45931:30774,45932:30781,45933:30783,45934:30785,45935:30786,45936:30787,45937:30788,45938:30790,45939:30792,45940:30793,45941:30794,45942:30795,45943:30797,45944:30799,45945:30801,45946:30803,45947:30804,45948:30808,45949:30809,45950:30810,45952:30811,45953:30812,45954:30814,45955:30815,45956:30816,45957:30817,45958:30818,45959:30819,45960:30820,45961:30821,45962:30822,45963:30823,45964:30824,45965:30825,45966:30831,45967:30832,45968:30833,45969:30834,45970:30835,45971:30836,45972:30837,45973:30838,45974:30840,45975:30841,45976:30842,45977:30843,45978:30845,45979:30846,45980:30847,45981:30848,45982:30849,45983:30850,45984:30851,45985:22330,45986:23581,45987:24120,45988:38271,45989:20607,45990:32928,45991:21378,45992:25950,45993:30021,45994:21809,45995:20513,45996:36229,45997:25220,45998:38046,45999:26397,46000:22066,46001:28526,46002:24034,46003:21557,46004:28818,46005:36710,46006:25199,46007:25764,46008:25507,46009:24443,46010:28552,46011:37108,46012:33251,46013:36784,46014:23576,46015:26216,46016:24561,46017:27785,46018:38472,46019:36225,46020:34924,46021:25745,46022:31216,46023:22478,46024:27225,46025:25104,46026:21576,46027:20056,46028:31243,46029:24809,46030:28548,46031:35802,46032:25215,46033:36894,46034:39563,46035:31204,46036:21507,46037:30196,46038:25345,46039:21273,46040:27744,46041:36831,46042:24347,46043:39536,46044:32827,46045:40831,46046:20360,46047:23610,46048:36196,46049:32709,46050:26021,46051:28861,46052:20805,46053:20914,46054:34411,46055:23815,46056:23456,46057:25277,46058:37228,46059:30068,46060:36364,46061:31264,46062:24833,46063:31609,46064:20167,46065:32504,46066:30597,46067:19985,46068:33261,46069:21021,46070:20986,46071:27249,46072:21416,46073:36487,46074:38148,46075:38607,46076:28353,46077:38500,46078:26970,46144:30852,46145:30853,46146:30854,46147:30856,46148:30858,46149:30859,46150:30863,46151:30864,46152:30866,46153:30868,46154:30869,46155:30870,46156:30873,46157:30877,46158:30878,46159:30880,46160:30882,46161:30884,46162:30886,46163:30888,46164:30889,46165:30890,46166:30891,46167:30892,46168:30893,46169:30894,46170:30895,46171:30901,46172:30902,46173:30903,46174:30904,46175:30906,46176:30907,46177:30908,46178:30909,46179:30911,46180:30912,46181:30914,46182:30915,46183:30916,46184:30918,46185:30919,46186:30920,46187:30924,46188:30925,46189:30926,46190:30927,46191:30929,46192:30930,46193:30931,46194:30934,46195:30935,46196:30936,46197:30938,46198:30939,46199:30940,46200:30941,46201:30942,46202:30943,46203:30944,46204:30945,46205:30946,46206:30947,46208:30948,46209:30949,46210:30950,46211:30951,46212:30953,46213:30954,46214:30955,46215:30957,46216:30958,46217:30959,46218:30960,46219:30961,46220:30963,46221:30965,46222:30966,46223:30968,46224:30969,46225:30971,46226:30972,46227:30973,46228:30974,46229:30975,46230:30976,46231:30978,46232:30979,46233:30980,46234:30982,46235:30983,46236:30984,46237:30985,46238:30986,46239:30987,46240:30988,46241:30784,46242:20648,46243:30679,46244:25616,46245:35302,46246:22788,46247:25571,46248:24029,46249:31359,46250:26941,46251:20256,46252:33337,46253:21912,46254:20018,46255:30126,46256:31383,46257:24162,46258:24202,46259:38383,46260:21019,46261:21561,46262:28810,46263:25462,46264:38180,46265:22402,46266:26149,46267:26943,46268:37255,46269:21767,46270:28147,46271:32431,46272:34850,46273:25139,46274:32496,46275:30133,46276:33576,46277:30913,46278:38604,46279:36766,46280:24904,46281:29943,46282:35789,46283:27492,46284:21050,46285:36176,46286:27425,46287:32874,46288:33905,46289:22257,46290:21254,46291:20174,46292:19995,46293:20945,46294:31895,46295:37259,46296:31751,46297:20419,46298:36479,46299:31713,46300:31388,46301:25703,46302:23828,46303:20652,46304:33030,46305:30209,46306:31929,46307:28140,46308:32736,46309:26449,46310:23384,46311:23544,46312:30923,46313:25774,46314:25619,46315:25514,46316:25387,46317:38169,46318:25645,46319:36798,46320:31572,46321:30249,46322:25171,46323:22823,46324:21574,46325:27513,46326:20643,46327:25140,46328:24102,46329:27526,46330:20195,46331:36151,46332:34955,46333:24453,46334:36910,46400:30989,46401:30990,46402:30991,46403:30992,46404:30993,46405:30994,46406:30996,46407:30997,46408:30998,46409:30999,46410:31000,46411:31001,46412:31002,46413:31003,46414:31004,46415:31005,46416:31007,46417:31008,46418:31009,46419:31010,46420:31011,46421:31013,46422:31014,46423:31015,46424:31016,46425:31017,46426:31018,46427:31019,46428:31020,46429:31021,46430:31022,46431:31023,46432:31024,46433:31025,46434:31026,46435:31027,46436:31029,46437:31030,46438:31031,46439:31032,46440:31033,46441:31037,46442:31039,46443:31042,46444:31043,46445:31044,46446:31045,46447:31047,46448:31050,46449:31051,46450:31052,46451:31053,46452:31054,46453:31055,46454:31056,46455:31057,46456:31058,46457:31060,46458:31061,46459:31064,46460:31065,46461:31073,46462:31075,46464:31076,46465:31078,46466:31081,46467:31082,46468:31083,46469:31084,46470:31086,46471:31088,46472:31089,46473:31090,46474:31091,46475:31092,46476:31093,46477:31094,46478:31097,46479:31099,46480:31100,46481:31101,46482:31102,46483:31103,46484:31106,46485:31107,46486:31110,46487:31111,46488:31112,46489:31113,46490:31115,46491:31116,46492:31117,46493:31118,46494:31120,46495:31121,46496:31122,46497:24608,46498:32829,46499:25285,46500:20025,46501:21333,46502:37112,46503:25528,46504:32966,46505:26086,46506:27694,46507:20294,46508:24814,46509:28129,46510:35806,46511:24377,46512:34507,46513:24403,46514:25377,46515:20826,46516:33633,46517:26723,46518:20992,46519:25443,46520:36424,46521:20498,46522:23707,46523:31095,46524:23548,46525:21040,46526:31291,46527:24764,46528:36947,46529:30423,46530:24503,46531:24471,46532:30340,46533:36460,46534:28783,46535:30331,46536:31561,46537:30634,46538:20979,46539:37011,46540:22564,46541:20302,46542:28404,46543:36842,46544:25932,46545:31515,46546:29380,46547:28068,46548:32735,46549:23265,46550:25269,46551:24213,46552:22320,46553:33922,46554:31532,46555:24093,46556:24351,46557:36882,46558:32532,46559:39072,46560:25474,46561:28359,46562:30872,46563:28857,46564:20856,46565:38747,46566:22443,46567:30005,46568:20291,46569:30008,46570:24215,46571:24806,46572:22880,46573:28096,46574:27583,46575:30857,46576:21500,46577:38613,46578:20939,46579:20993,46580:25481,46581:21514,46582:38035,46583:35843,46584:36300,46585:29241,46586:30879,46587:34678,46588:36845,46589:35853,46590:21472,46656:31123,46657:31124,46658:31125,46659:31126,46660:31127,46661:31128,46662:31129,46663:31131,46664:31132,46665:31133,46666:31134,46667:31135,46668:31136,46669:31137,46670:31138,46671:31139,46672:31140,46673:31141,46674:31142,46675:31144,46676:31145,46677:31146,46678:31147,46679:31148,46680:31149,46681:31150,46682:31151,46683:31152,46684:31153,46685:31154,46686:31156,46687:31157,46688:31158,46689:31159,46690:31160,46691:31164,46692:31167,46693:31170,46694:31172,46695:31173,46696:31175,46697:31176,46698:31178,46699:31180,46700:31182,46701:31183,46702:31184,46703:31187,46704:31188,46705:31190,46706:31191,46707:31193,46708:31194,46709:31195,46710:31196,46711:31197,46712:31198,46713:31200,46714:31201,46715:31202,46716:31205,46717:31208,46718:31210,46720:31212,46721:31214,46722:31217,46723:31218,46724:31219,46725:31220,46726:31221,46727:31222,46728:31223,46729:31225,46730:31226,46731:31228,46732:31230,46733:31231,46734:31233,46735:31236,46736:31237,46737:31239,46738:31240,46739:31241,46740:31242,46741:31244,46742:31247,46743:31248,46744:31249,46745:31250,46746:31251,46747:31253,46748:31254,46749:31256,46750:31257,46751:31259,46752:31260,46753:19969,46754:30447,46755:21486,46756:38025,46757:39030,46758:40718,46759:38189,46760:23450,46761:35746,46762:20002,46763:19996,46764:20908,46765:33891,46766:25026,46767:21160,46768:26635,46769:20375,46770:24683,46771:20923,46772:27934,46773:20828,46774:25238,46775:26007,46776:38497,46777:35910,46778:36887,46779:30168,46780:37117,46781:30563,46782:27602,46783:29322,46784:29420,46785:35835,46786:22581,46787:30585,46788:36172,46789:26460,46790:38208,46791:32922,46792:24230,46793:28193,46794:22930,46795:31471,46796:30701,46797:38203,46798:27573,46799:26029,46800:32526,46801:22534,46802:20817,46803:38431,46804:23545,46805:22697,46806:21544,46807:36466,46808:25958,46809:39039,46810:22244,46811:38045,46812:30462,46813:36929,46814:25479,46815:21702,46816:22810,46817:22842,46818:22427,46819:36530,46820:26421,46821:36346,46822:33333,46823:21057,46824:24816,46825:22549,46826:34558,46827:23784,46828:40517,46829:20420,46830:39069,46831:35769,46832:23077,46833:24694,46834:21380,46835:25212,46836:36943,46837:37122,46838:39295,46839:24681,46840:32780,46841:20799,46842:32819,46843:23572,46844:39285,46845:27953,46846:20108,46912:31261,46913:31263,46914:31265,46915:31266,46916:31268,46917:31269,46918:31270,46919:31271,46920:31272,46921:31273,46922:31274,46923:31275,46924:31276,46925:31277,46926:31278,46927:31279,46928:31280,46929:31281,46930:31282,46931:31284,46932:31285,46933:31286,46934:31288,46935:31290,46936:31294,46937:31296,46938:31297,46939:31298,46940:31299,46941:31300,46942:31301,46943:31303,46944:31304,46945:31305,46946:31306,46947:31307,46948:31308,46949:31309,46950:31310,46951:31311,46952:31312,46953:31314,46954:31315,46955:31316,46956:31317,46957:31318,46958:31320,46959:31321,46960:31322,46961:31323,46962:31324,46963:31325,46964:31326,46965:31327,46966:31328,46967:31329,46968:31330,46969:31331,46970:31332,46971:31333,46972:31334,46973:31335,46974:31336,46976:31337,46977:31338,46978:31339,46979:31340,46980:31341,46981:31342,46982:31343,46983:31345,46984:31346,46985:31347,46986:31349,46987:31355,46988:31356,46989:31357,46990:31358,46991:31362,46992:31365,46993:31367,46994:31369,46995:31370,46996:31371,46997:31372,46998:31374,46999:31375,47000:31376,47001:31379,47002:31380,47003:31385,47004:31386,47005:31387,47006:31390,47007:31393,47008:31394,47009:36144,47010:21457,47011:32602,47012:31567,47013:20240,47014:20047,47015:38400,47016:27861,47017:29648,47018:34281,47019:24070,47020:30058,47021:32763,47022:27146,47023:30718,47024:38034,47025:32321,47026:20961,47027:28902,47028:21453,47029:36820,47030:33539,47031:36137,47032:29359,47033:39277,47034:27867,47035:22346,47036:33459,47037:26041,47038:32938,47039:25151,47040:38450,47041:22952,47042:20223,47043:35775,47044:32442,47045:25918,47046:33778,47047:38750,47048:21857,47049:39134,47050:32933,47051:21290,47052:35837,47053:21536,47054:32954,47055:24223,47056:27832,47057:36153,47058:33452,47059:37210,47060:21545,47061:27675,47062:20998,47063:32439,47064:22367,47065:28954,47066:27774,47067:31881,47068:22859,47069:20221,47070:24575,47071:24868,47072:31914,47073:20016,47074:23553,47075:26539,47076:34562,47077:23792,47078:38155,47079:39118,47080:30127,47081:28925,47082:36898,47083:20911,47084:32541,47085:35773,47086:22857,47087:20964,47088:20315,47089:21542,47090:22827,47091:25975,47092:32932,47093:23413,47094:25206,47095:25282,47096:36752,47097:24133,47098:27679,47099:31526,47100:20239,47101:20440,47102:26381,47168:31395,47169:31396,47170:31399,47171:31401,47172:31402,47173:31403,47174:31406,47175:31407,47176:31408,47177:31409,47178:31410,47179:31412,47180:31413,47181:31414,47182:31415,47183:31416,47184:31417,47185:31418,47186:31419,47187:31420,47188:31421,47189:31422,47190:31424,47191:31425,47192:31426,47193:31427,47194:31428,47195:31429,47196:31430,47197:31431,47198:31432,47199:31433,47200:31434,47201:31436,47202:31437,47203:31438,47204:31439,47205:31440,47206:31441,47207:31442,47208:31443,47209:31444,47210:31445,47211:31447,47212:31448,47213:31450,47214:31451,47215:31452,47216:31453,47217:31457,47218:31458,47219:31460,47220:31463,47221:31464,47222:31465,47223:31466,47224:31467,47225:31468,47226:31470,47227:31472,47228:31473,47229:31474,47230:31475,47232:31476,47233:31477,47234:31478,47235:31479,47236:31480,47237:31483,47238:31484,47239:31486,47240:31488,47241:31489,47242:31490,47243:31493,47244:31495,47245:31497,47246:31500,47247:31501,47248:31502,47249:31504,47250:31506,47251:31507,47252:31510,47253:31511,47254:31512,47255:31514,47256:31516,47257:31517,47258:31519,47259:31521,47260:31522,47261:31523,47262:31527,47263:31529,47264:31533,47265:28014,47266:28074,47267:31119,47268:34993,47269:24343,47270:29995,47271:25242,47272:36741,47273:20463,47274:37340,47275:26023,47276:33071,47277:33105,47278:24220,47279:33104,47280:36212,47281:21103,47282:35206,47283:36171,47284:22797,47285:20613,47286:20184,47287:38428,47288:29238,47289:33145,47290:36127,47291:23500,47292:35747,47293:38468,47294:22919,47295:32538,47296:21648,47297:22134,47298:22030,47299:35813,47300:25913,47301:27010,47302:38041,47303:30422,47304:28297,47305:24178,47306:29976,47307:26438,47308:26577,47309:31487,47310:32925,47311:36214,47312:24863,47313:31174,47314:25954,47315:36195,47316:20872,47317:21018,47318:38050,47319:32568,47320:32923,47321:32434,47322:23703,47323:28207,47324:26464,47325:31705,47326:30347,47327:39640,47328:33167,47329:32660,47330:31957,47331:25630,47332:38224,47333:31295,47334:21578,47335:21733,47336:27468,47337:25601,47338:25096,47339:40509,47340:33011,47341:30105,47342:21106,47343:38761,47344:33883,47345:26684,47346:34532,47347:38401,47348:38548,47349:38124,47350:20010,47351:21508,47352:32473,47353:26681,47354:36319,47355:32789,47356:26356,47357:24218,47358:32697,47424:31535,47425:31536,47426:31538,47427:31540,47428:31541,47429:31542,47430:31543,47431:31545,47432:31547,47433:31549,47434:31551,47435:31552,47436:31553,47437:31554,47438:31555,47439:31556,47440:31558,47441:31560,47442:31562,47443:31565,47444:31566,47445:31571,47446:31573,47447:31575,47448:31577,47449:31580,47450:31582,47451:31583,47452:31585,47453:31587,47454:31588,47455:31589,47456:31590,47457:31591,47458:31592,47459:31593,47460:31594,47461:31595,47462:31596,47463:31597,47464:31599,47465:31600,47466:31603,47467:31604,47468:31606,47469:31608,47470:31610,47471:31612,47472:31613,47473:31615,47474:31617,47475:31618,47476:31619,47477:31620,47478:31622,47479:31623,47480:31624,47481:31625,47482:31626,47483:31627,47484:31628,47485:31630,47486:31631,47488:31633,47489:31634,47490:31635,47491:31638,47492:31640,47493:31641,47494:31642,47495:31643,47496:31646,47497:31647,47498:31648,47499:31651,47500:31652,47501:31653,47502:31662,47503:31663,47504:31664,47505:31666,47506:31667,47507:31669,47508:31670,47509:31671,47510:31673,47511:31674,47512:31675,47513:31676,47514:31677,47515:31678,47516:31679,47517:31680,47518:31682,47519:31683,47520:31684,47521:22466,47522:32831,47523:26775,47524:24037,47525:25915,47526:21151,47527:24685,47528:40858,47529:20379,47530:36524,47531:20844,47532:23467,47533:24339,47534:24041,47535:27742,47536:25329,47537:36129,47538:20849,47539:38057,47540:21246,47541:27807,47542:33503,47543:29399,47544:22434,47545:26500,47546:36141,47547:22815,47548:36764,47549:33735,47550:21653,47551:31629,47552:20272,47553:27837,47554:23396,47555:22993,47556:40723,47557:21476,47558:34506,47559:39592,47560:35895,47561:32929,47562:25925,47563:39038,47564:22266,47565:38599,47566:21038,47567:29916,47568:21072,47569:23521,47570:25346,47571:35074,47572:20054,47573:25296,47574:24618,47575:26874,47576:20851,47577:23448,47578:20896,47579:35266,47580:31649,47581:39302,47582:32592,47583:24815,47584:28748,47585:36143,47586:20809,47587:24191,47588:36891,47589:29808,47590:35268,47591:22317,47592:30789,47593:24402,47594:40863,47595:38394,47596:36712,47597:39740,47598:35809,47599:30328,47600:26690,47601:26588,47602:36330,47603:36149,47604:21053,47605:36746,47606:28378,47607:26829,47608:38149,47609:37101,47610:22269,47611:26524,47612:35065,47613:36807,47614:21704,47680:31685,47681:31688,47682:31689,47683:31690,47684:31691,47685:31693,47686:31694,47687:31695,47688:31696,47689:31698,47690:31700,47691:31701,47692:31702,47693:31703,47694:31704,47695:31707,47696:31708,47697:31710,47698:31711,47699:31712,47700:31714,47701:31715,47702:31716,47703:31719,47704:31720,47705:31721,47706:31723,47707:31724,47708:31725,47709:31727,47710:31728,47711:31730,47712:31731,47713:31732,47714:31733,47715:31734,47716:31736,47717:31737,47718:31738,47719:31739,47720:31741,47721:31743,47722:31744,47723:31745,47724:31746,47725:31747,47726:31748,47727:31749,47728:31750,47729:31752,47730:31753,47731:31754,47732:31757,47733:31758,47734:31760,47735:31761,47736:31762,47737:31763,47738:31764,47739:31765,47740:31767,47741:31768,47742:31769,47744:31770,47745:31771,47746:31772,47747:31773,47748:31774,47749:31776,47750:31777,47751:31778,47752:31779,47753:31780,47754:31781,47755:31784,47756:31785,47757:31787,47758:31788,47759:31789,47760:31790,47761:31791,47762:31792,47763:31793,47764:31794,47765:31795,47766:31796,47767:31797,47768:31798,47769:31799,47770:31801,47771:31802,47772:31803,47773:31804,47774:31805,47775:31806,47776:31810,47777:39608,47778:23401,47779:28023,47780:27686,47781:20133,47782:23475,47783:39559,47784:37219,47785:25000,47786:37039,47787:38889,47788:21547,47789:28085,47790:23506,47791:20989,47792:21898,47793:32597,47794:32752,47795:25788,47796:25421,47797:26097,47798:25022,47799:24717,47800:28938,47801:27735,47802:27721,47803:22831,47804:26477,47805:33322,47806:22741,47807:22158,47808:35946,47809:27627,47810:37085,47811:22909,47812:32791,47813:21495,47814:28009,47815:21621,47816:21917,47817:33655,47818:33743,47819:26680,47820:31166,47821:21644,47822:20309,47823:21512,47824:30418,47825:35977,47826:38402,47827:27827,47828:28088,47829:36203,47830:35088,47831:40548,47832:36154,47833:22079,47834:40657,47835:30165,47836:24456,47837:29408,47838:24680,47839:21756,47840:20136,47841:27178,47842:34913,47843:24658,47844:36720,47845:21700,47846:28888,47847:34425,47848:40511,47849:27946,47850:23439,47851:24344,47852:32418,47853:21897,47854:20399,47855:29492,47856:21564,47857:21402,47858:20505,47859:21518,47860:21628,47861:20046,47862:24573,47863:29786,47864:22774,47865:33899,47866:32993,47867:34676,47868:29392,47869:31946,47870:28246,47936:31811,47937:31812,47938:31813,47939:31814,47940:31815,47941:31816,47942:31817,47943:31818,47944:31819,47945:31820,47946:31822,47947:31823,47948:31824,47949:31825,47950:31826,47951:31827,47952:31828,47953:31829,47954:31830,47955:31831,47956:31832,47957:31833,47958:31834,47959:31835,47960:31836,47961:31837,47962:31838,47963:31839,47964:31840,47965:31841,47966:31842,47967:31843,47968:31844,47969:31845,47970:31846,47971:31847,47972:31848,47973:31849,47974:31850,47975:31851,47976:31852,47977:31853,47978:31854,47979:31855,47980:31856,47981:31857,47982:31858,47983:31861,47984:31862,47985:31863,47986:31864,47987:31865,47988:31866,47989:31870,47990:31871,47991:31872,47992:31873,47993:31874,47994:31875,47995:31876,47996:31877,47997:31878,47998:31879,48000:31880,48001:31882,48002:31883,48003:31884,48004:31885,48005:31886,48006:31887,48007:31888,48008:31891,48009:31892,48010:31894,48011:31897,48012:31898,48013:31899,48014:31904,48015:31905,48016:31907,48017:31910,48018:31911,48019:31912,48020:31913,48021:31915,48022:31916,48023:31917,48024:31919,48025:31920,48026:31924,48027:31925,48028:31926,48029:31927,48030:31928,48031:31930,48032:31931,48033:24359,48034:34382,48035:21804,48036:25252,48037:20114,48038:27818,48039:25143,48040:33457,48041:21719,48042:21326,48043:29502,48044:28369,48045:30011,48046:21010,48047:21270,48048:35805,48049:27088,48050:24458,48051:24576,48052:28142,48053:22351,48054:27426,48055:29615,48056:26707,48057:36824,48058:32531,48059:25442,48060:24739,48061:21796,48062:30186,48063:35938,48064:28949,48065:28067,48066:23462,48067:24187,48068:33618,48069:24908,48070:40644,48071:30970,48072:34647,48073:31783,48074:30343,48075:20976,48076:24822,48077:29004,48078:26179,48079:24140,48080:24653,48081:35854,48082:28784,48083:25381,48084:36745,48085:24509,48086:24674,48087:34516,48088:22238,48089:27585,48090:24724,48091:24935,48092:21321,48093:24800,48094:26214,48095:36159,48096:31229,48097:20250,48098:28905,48099:27719,48100:35763,48101:35826,48102:32472,48103:33636,48104:26127,48105:23130,48106:39746,48107:27985,48108:28151,48109:35905,48110:27963,48111:20249,48112:28779,48113:33719,48114:25110,48115:24785,48116:38669,48117:36135,48118:31096,48119:20987,48120:22334,48121:22522,48122:26426,48123:30072,48124:31293,48125:31215,48126:31637,48192:31935,48193:31936,48194:31938,48195:31939,48196:31940,48197:31942,48198:31945,48199:31947,48200:31950,48201:31951,48202:31952,48203:31953,48204:31954,48205:31955,48206:31956,48207:31960,48208:31962,48209:31963,48210:31965,48211:31966,48212:31969,48213:31970,48214:31971,48215:31972,48216:31973,48217:31974,48218:31975,48219:31977,48220:31978,48221:31979,48222:31980,48223:31981,48224:31982,48225:31984,48226:31985,48227:31986,48228:31987,48229:31988,48230:31989,48231:31990,48232:31991,48233:31993,48234:31994,48235:31996,48236:31997,48237:31998,48238:31999,48239:32000,48240:32001,48241:32002,48242:32003,48243:32004,48244:32005,48245:32006,48246:32007,48247:32008,48248:32009,48249:32011,48250:32012,48251:32013,48252:32014,48253:32015,48254:32016,48256:32017,48257:32018,48258:32019,48259:32020,48260:32021,48261:32022,48262:32023,48263:32024,48264:32025,48265:32026,48266:32027,48267:32028,48268:32029,48269:32030,48270:32031,48271:32033,48272:32035,48273:32036,48274:32037,48275:32038,48276:32040,48277:32041,48278:32042,48279:32044,48280:32045,48281:32046,48282:32048,48283:32049,48284:32050,48285:32051,48286:32052,48287:32053,48288:32054,48289:32908,48290:39269,48291:36857,48292:28608,48293:35749,48294:40481,48295:23020,48296:32489,48297:32521,48298:21513,48299:26497,48300:26840,48301:36753,48302:31821,48303:38598,48304:21450,48305:24613,48306:30142,48307:27762,48308:21363,48309:23241,48310:32423,48311:25380,48312:20960,48313:33034,48314:24049,48315:34015,48316:25216,48317:20864,48318:23395,48319:20238,48320:31085,48321:21058,48322:24760,48323:27982,48324:23492,48325:23490,48326:35745,48327:35760,48328:26082,48329:24524,48330:38469,48331:22931,48332:32487,48333:32426,48334:22025,48335:26551,48336:22841,48337:20339,48338:23478,48339:21152,48340:33626,48341:39050,48342:36158,48343:30002,48344:38078,48345:20551,48346:31292,48347:20215,48348:26550,48349:39550,48350:23233,48351:27516,48352:30417,48353:22362,48354:23574,48355:31546,48356:38388,48357:29006,48358:20860,48359:32937,48360:33392,48361:22904,48362:32516,48363:33575,48364:26816,48365:26604,48366:30897,48367:30839,48368:25315,48369:25441,48370:31616,48371:20461,48372:21098,48373:20943,48374:33616,48375:27099,48376:37492,48377:36341,48378:36145,48379:35265,48380:38190,48381:31661,48382:20214,48448:32055,48449:32056,48450:32057,48451:32058,48452:32059,48453:32060,48454:32061,48455:32062,48456:32063,48457:32064,48458:32065,48459:32066,48460:32067,48461:32068,48462:32069,48463:32070,48464:32071,48465:32072,48466:32073,48467:32074,48468:32075,48469:32076,48470:32077,48471:32078,48472:32079,48473:32080,48474:32081,48475:32082,48476:32083,48477:32084,48478:32085,48479:32086,48480:32087,48481:32088,48482:32089,48483:32090,48484:32091,48485:32092,48486:32093,48487:32094,48488:32095,48489:32096,48490:32097,48491:32098,48492:32099,48493:32100,48494:32101,48495:32102,48496:32103,48497:32104,48498:32105,48499:32106,48500:32107,48501:32108,48502:32109,48503:32111,48504:32112,48505:32113,48506:32114,48507:32115,48508:32116,48509:32117,48510:32118,48512:32120,48513:32121,48514:32122,48515:32123,48516:32124,48517:32125,48518:32126,48519:32127,48520:32128,48521:32129,48522:32130,48523:32131,48524:32132,48525:32133,48526:32134,48527:32135,48528:32136,48529:32137,48530:32138,48531:32139,48532:32140,48533:32141,48534:32142,48535:32143,48536:32144,48537:32145,48538:32146,48539:32147,48540:32148,48541:32149,48542:32150,48543:32151,48544:32152,48545:20581,48546:33328,48547:21073,48548:39279,48549:28176,48550:28293,48551:28071,48552:24314,48553:20725,48554:23004,48555:23558,48556:27974,48557:27743,48558:30086,48559:33931,48560:26728,48561:22870,48562:35762,48563:21280,48564:37233,48565:38477,48566:34121,48567:26898,48568:30977,48569:28966,48570:33014,48571:20132,48572:37066,48573:27975,48574:39556,48575:23047,48576:22204,48577:25605,48578:38128,48579:30699,48580:20389,48581:33050,48582:29409,48583:35282,48584:39290,48585:32564,48586:32478,48587:21119,48588:25945,48589:37237,48590:36735,48591:36739,48592:21483,48593:31382,48594:25581,48595:25509,48596:30342,48597:31224,48598:34903,48599:38454,48600:25130,48601:21163,48602:33410,48603:26708,48604:26480,48605:25463,48606:30571,48607:31469,48608:27905,48609:32467,48610:35299,48611:22992,48612:25106,48613:34249,48614:33445,48615:30028,48616:20511,48617:20171,48618:30117,48619:35819,48620:23626,48621:24062,48622:31563,48623:26020,48624:37329,48625:20170,48626:27941,48627:35167,48628:32039,48629:38182,48630:20165,48631:35880,48632:36827,48633:38771,48634:26187,48635:31105,48636:36817,48637:28908,48638:28024,48704:32153,48705:32154,48706:32155,48707:32156,48708:32157,48709:32158,48710:32159,48711:32160,48712:32161,48713:32162,48714:32163,48715:32164,48716:32165,48717:32167,48718:32168,48719:32169,48720:32170,48721:32171,48722:32172,48723:32173,48724:32175,48725:32176,48726:32177,48727:32178,48728:32179,48729:32180,48730:32181,48731:32182,48732:32183,48733:32184,48734:32185,48735:32186,48736:32187,48737:32188,48738:32189,48739:32190,48740:32191,48741:32192,48742:32193,48743:32194,48744:32195,48745:32196,48746:32197,48747:32198,48748:32199,48749:32200,48750:32201,48751:32202,48752:32203,48753:32204,48754:32205,48755:32206,48756:32207,48757:32208,48758:32209,48759:32210,48760:32211,48761:32212,48762:32213,48763:32214,48764:32215,48765:32216,48766:32217,48768:32218,48769:32219,48770:32220,48771:32221,48772:32222,48773:32223,48774:32224,48775:32225,48776:32226,48777:32227,48778:32228,48779:32229,48780:32230,48781:32231,48782:32232,48783:32233,48784:32234,48785:32235,48786:32236,48787:32237,48788:32238,48789:32239,48790:32240,48791:32241,48792:32242,48793:32243,48794:32244,48795:32245,48796:32246,48797:32247,48798:32248,48799:32249,48800:32250,48801:23613,48802:21170,48803:33606,48804:20834,48805:33550,48806:30555,48807:26230,48808:40120,48809:20140,48810:24778,48811:31934,48812:31923,48813:32463,48814:20117,48815:35686,48816:26223,48817:39048,48818:38745,48819:22659,48820:25964,48821:38236,48822:24452,48823:30153,48824:38742,48825:31455,48826:31454,48827:20928,48828:28847,48829:31384,48830:25578,48831:31350,48832:32416,48833:29590,48834:38893,48835:20037,48836:28792,48837:20061,48838:37202,48839:21417,48840:25937,48841:26087,48842:33276,48843:33285,48844:21646,48845:23601,48846:30106,48847:38816,48848:25304,48849:29401,48850:30141,48851:23621,48852:39545,48853:33738,48854:23616,48855:21632,48856:30697,48857:20030,48858:27822,48859:32858,48860:25298,48861:25454,48862:24040,48863:20855,48864:36317,48865:36382,48866:38191,48867:20465,48868:21477,48869:24807,48870:28844,48871:21095,48872:25424,48873:40515,48874:23071,48875:20518,48876:30519,48877:21367,48878:32482,48879:25733,48880:25899,48881:25225,48882:25496,48883:20500,48884:29237,48885:35273,48886:20915,48887:35776,48888:32477,48889:22343,48890:33740,48891:38055,48892:20891,48893:21531,48894:23803,48960:32251,48961:32252,48962:32253,48963:32254,48964:32255,48965:32256,48966:32257,48967:32258,48968:32259,48969:32260,48970:32261,48971:32262,48972:32263,48973:32264,48974:32265,48975:32266,48976:32267,48977:32268,48978:32269,48979:32270,48980:32271,48981:32272,48982:32273,48983:32274,48984:32275,48985:32276,48986:32277,48987:32278,48988:32279,48989:32280,48990:32281,48991:32282,48992:32283,48993:32284,48994:32285,48995:32286,48996:32287,48997:32288,48998:32289,48999:32290,49000:32291,49001:32292,49002:32293,49003:32294,49004:32295,49005:32296,49006:32297,49007:32298,49008:32299,49009:32300,49010:32301,49011:32302,49012:32303,49013:32304,49014:32305,49015:32306,49016:32307,49017:32308,49018:32309,49019:32310,49020:32311,49021:32312,49022:32313,49024:32314,49025:32316,49026:32317,49027:32318,49028:32319,49029:32320,49030:32322,49031:32323,49032:32324,49033:32325,49034:32326,49035:32328,49036:32329,49037:32330,49038:32331,49039:32332,49040:32333,49041:32334,49042:32335,49043:32336,49044:32337,49045:32338,49046:32339,49047:32340,49048:32341,49049:32342,49050:32343,49051:32344,49052:32345,49053:32346,49054:32347,49055:32348,49056:32349,49057:20426,49058:31459,49059:27994,49060:37089,49061:39567,49062:21888,49063:21654,49064:21345,49065:21679,49066:24320,49067:25577,49068:26999,49069:20975,49070:24936,49071:21002,49072:22570,49073:21208,49074:22350,49075:30733,49076:30475,49077:24247,49078:24951,49079:31968,49080:25179,49081:25239,49082:20130,49083:28821,49084:32771,49085:25335,49086:28900,49087:38752,49088:22391,49089:33499,49090:26607,49091:26869,49092:30933,49093:39063,49094:31185,49095:22771,49096:21683,49097:21487,49098:28212,49099:20811,49100:21051,49101:23458,49102:35838,49103:32943,49104:21827,49105:22438,49106:24691,49107:22353,49108:21549,49109:31354,49110:24656,49111:23380,49112:25511,49113:25248,49114:21475,49115:25187,49116:23495,49117:26543,49118:21741,49119:31391,49120:33510,49121:37239,49122:24211,49123:35044,49124:22840,49125:22446,49126:25358,49127:36328,49128:33007,49129:22359,49130:31607,49131:20393,49132:24555,49133:23485,49134:27454,49135:21281,49136:31568,49137:29378,49138:26694,49139:30719,49140:30518,49141:26103,49142:20917,49143:20111,49144:30420,49145:23743,49146:31397,49147:33909,49148:22862,49149:39745,49150:20608,49216:32350,49217:32351,49218:32352,49219:32353,49220:32354,49221:32355,49222:32356,49223:32357,49224:32358,49225:32359,49226:32360,49227:32361,49228:32362,49229:32363,49230:32364,49231:32365,49232:32366,49233:32367,49234:32368,49235:32369,49236:32370,49237:32371,49238:32372,49239:32373,49240:32374,49241:32375,49242:32376,49243:32377,49244:32378,49245:32379,49246:32380,49247:32381,49248:32382,49249:32383,49250:32384,49251:32385,49252:32387,49253:32388,49254:32389,49255:32390,49256:32391,49257:32392,49258:32393,49259:32394,49260:32395,49261:32396,49262:32397,49263:32398,49264:32399,49265:32400,49266:32401,49267:32402,49268:32403,49269:32404,49270:32405,49271:32406,49272:32407,49273:32408,49274:32409,49275:32410,49276:32412,49277:32413,49278:32414,49280:32430,49281:32436,49282:32443,49283:32444,49284:32470,49285:32484,49286:32492,49287:32505,49288:32522,49289:32528,49290:32542,49291:32567,49292:32569,49293:32571,49294:32572,49295:32573,49296:32574,49297:32575,49298:32576,49299:32577,49300:32579,49301:32582,49302:32583,49303:32584,49304:32585,49305:32586,49306:32587,49307:32588,49308:32589,49309:32590,49310:32591,49311:32594,49312:32595,49313:39304,49314:24871,49315:28291,49316:22372,49317:26118,49318:25414,49319:22256,49320:25324,49321:25193,49322:24275,49323:38420,49324:22403,49325:25289,49326:21895,49327:34593,49328:33098,49329:36771,49330:21862,49331:33713,49332:26469,49333:36182,49334:34013,49335:23146,49336:26639,49337:25318,49338:31726,49339:38417,49340:20848,49341:28572,49342:35888,49343:25597,49344:35272,49345:25042,49346:32518,49347:28866,49348:28389,49349:29701,49350:27028,49351:29436,49352:24266,49353:37070,49354:26391,49355:28010,49356:25438,49357:21171,49358:29282,49359:32769,49360:20332,49361:23013,49362:37226,49363:28889,49364:28061,49365:21202,49366:20048,49367:38647,49368:38253,49369:34174,49370:30922,49371:32047,49372:20769,49373:22418,49374:25794,49375:32907,49376:31867,49377:27882,49378:26865,49379:26974,49380:20919,49381:21400,49382:26792,49383:29313,49384:40654,49385:31729,49386:29432,49387:31163,49388:28435,49389:29702,49390:26446,49391:37324,49392:40100,49393:31036,49394:33673,49395:33620,49396:21519,49397:26647,49398:20029,49399:21385,49400:21169,49401:30782,49402:21382,49403:21033,49404:20616,49405:20363,49406:20432,49472:32598,49473:32601,49474:32603,49475:32604,49476:32605,49477:32606,49478:32608,49479:32611,49480:32612,49481:32613,49482:32614,49483:32615,49484:32619,49485:32620,49486:32621,49487:32623,49488:32624,49489:32627,49490:32629,49491:32630,49492:32631,49493:32632,49494:32634,49495:32635,49496:32636,49497:32637,49498:32639,49499:32640,49500:32642,49501:32643,49502:32644,49503:32645,49504:32646,49505:32647,49506:32648,49507:32649,49508:32651,49509:32653,49510:32655,49511:32656,49512:32657,49513:32658,49514:32659,49515:32661,49516:32662,49517:32663,49518:32664,49519:32665,49520:32667,49521:32668,49522:32672,49523:32674,49524:32675,49525:32677,49526:32678,49527:32680,49528:32681,49529:32682,49530:32683,49531:32684,49532:32685,49533:32686,49534:32689,49536:32691,49537:32692,49538:32693,49539:32694,49540:32695,49541:32698,49542:32699,49543:32702,49544:32704,49545:32706,49546:32707,49547:32708,49548:32710,49549:32711,49550:32712,49551:32713,49552:32715,49553:32717,49554:32719,49555:32720,49556:32721,49557:32722,49558:32723,49559:32726,49560:32727,49561:32729,49562:32730,49563:32731,49564:32732,49565:32733,49566:32734,49567:32738,49568:32739,49569:30178,49570:31435,49571:31890,49572:27813,49573:38582,49574:21147,49575:29827,49576:21737,49577:20457,49578:32852,49579:33714,49580:36830,49581:38256,49582:24265,49583:24604,49584:28063,49585:24088,49586:25947,49587:33080,49588:38142,49589:24651,49590:28860,49591:32451,49592:31918,49593:20937,49594:26753,49595:31921,49596:33391,49597:20004,49598:36742,49599:37327,49600:26238,49601:20142,49602:35845,49603:25769,49604:32842,49605:20698,49606:30103,49607:29134,49608:23525,49609:36797,49610:28518,49611:20102,49612:25730,49613:38243,49614:24278,49615:26009,49616:21015,49617:35010,49618:28872,49619:21155,49620:29454,49621:29747,49622:26519,49623:30967,49624:38678,49625:20020,49626:37051,49627:40158,49628:28107,49629:20955,49630:36161,49631:21533,49632:25294,49633:29618,49634:33777,49635:38646,49636:40836,49637:38083,49638:20278,49639:32666,49640:20940,49641:28789,49642:38517,49643:23725,49644:39046,49645:21478,49646:20196,49647:28316,49648:29705,49649:27060,49650:30827,49651:39311,49652:30041,49653:21016,49654:30244,49655:27969,49656:26611,49657:20845,49658:40857,49659:32843,49660:21657,49661:31548,49662:31423,49728:32740,49729:32743,49730:32744,49731:32746,49732:32747,49733:32748,49734:32749,49735:32751,49736:32754,49737:32756,49738:32757,49739:32758,49740:32759,49741:32760,49742:32761,49743:32762,49744:32765,49745:32766,49746:32767,49747:32770,49748:32775,49749:32776,49750:32777,49751:32778,49752:32782,49753:32783,49754:32785,49755:32787,49756:32794,49757:32795,49758:32797,49759:32798,49760:32799,49761:32801,49762:32803,49763:32804,49764:32811,49765:32812,49766:32813,49767:32814,49768:32815,49769:32816,49770:32818,49771:32820,49772:32825,49773:32826,49774:32828,49775:32830,49776:32832,49777:32833,49778:32836,49779:32837,49780:32839,49781:32840,49782:32841,49783:32846,49784:32847,49785:32848,49786:32849,49787:32851,49788:32853,49789:32854,49790:32855,49792:32857,49793:32859,49794:32860,49795:32861,49796:32862,49797:32863,49798:32864,49799:32865,49800:32866,49801:32867,49802:32868,49803:32869,49804:32870,49805:32871,49806:32872,49807:32875,49808:32876,49809:32877,49810:32878,49811:32879,49812:32880,49813:32882,49814:32883,49815:32884,49816:32885,49817:32886,49818:32887,49819:32888,49820:32889,49821:32890,49822:32891,49823:32892,49824:32893,49825:38534,49826:22404,49827:25314,49828:38471,49829:27004,49830:23044,49831:25602,49832:31699,49833:28431,49834:38475,49835:33446,49836:21346,49837:39045,49838:24208,49839:28809,49840:25523,49841:21348,49842:34383,49843:40065,49844:40595,49845:30860,49846:38706,49847:36335,49848:36162,49849:40575,49850:28510,49851:31108,49852:24405,49853:38470,49854:25134,49855:39540,49856:21525,49857:38109,49858:20387,49859:26053,49860:23653,49861:23649,49862:32533,49863:34385,49864:27695,49865:24459,49866:29575,49867:28388,49868:32511,49869:23782,49870:25371,49871:23402,49872:28390,49873:21365,49874:20081,49875:25504,49876:30053,49877:25249,49878:36718,49879:20262,49880:20177,49881:27814,49882:32438,49883:35770,49884:33821,49885:34746,49886:32599,49887:36923,49888:38179,49889:31657,49890:39585,49891:35064,49892:33853,49893:27931,49894:39558,49895:32476,49896:22920,49897:40635,49898:29595,49899:30721,49900:34434,49901:39532,49902:39554,49903:22043,49904:21527,49905:22475,49906:20080,49907:40614,49908:21334,49909:36808,49910:33033,49911:30610,49912:39314,49913:34542,49914:28385,49915:34067,49916:26364,49917:24930,49918:28459,49984:32894,49985:32897,49986:32898,49987:32901,49988:32904,49989:32906,49990:32909,49991:32910,49992:32911,49993:32912,49994:32913,49995:32914,49996:32916,49997:32917,49998:32919,49999:32921,50000:32926,50001:32931,50002:32934,50003:32935,50004:32936,50005:32940,50006:32944,50007:32947,50008:32949,50009:32950,50010:32952,50011:32953,50012:32955,50013:32965,50014:32967,50015:32968,50016:32969,50017:32970,50018:32971,50019:32975,50020:32976,50021:32977,50022:32978,50023:32979,50024:32980,50025:32981,50026:32984,50027:32991,50028:32992,50029:32994,50030:32995,50031:32998,50032:33006,50033:33013,50034:33015,50035:33017,50036:33019,50037:33022,50038:33023,50039:33024,50040:33025,50041:33027,50042:33028,50043:33029,50044:33031,50045:33032,50046:33035,50048:33036,50049:33045,50050:33047,50051:33049,50052:33051,50053:33052,50054:33053,50055:33055,50056:33056,50057:33057,50058:33058,50059:33059,50060:33060,50061:33061,50062:33062,50063:33063,50064:33064,50065:33065,50066:33066,50067:33067,50068:33069,50069:33070,50070:33072,50071:33075,50072:33076,50073:33077,50074:33079,50075:33081,50076:33082,50077:33083,50078:33084,50079:33085,50080:33087,50081:35881,50082:33426,50083:33579,50084:30450,50085:27667,50086:24537,50087:33725,50088:29483,50089:33541,50090:38170,50091:27611,50092:30683,50093:38086,50094:21359,50095:33538,50096:20882,50097:24125,50098:35980,50099:36152,50100:20040,50101:29611,50102:26522,50103:26757,50104:37238,50105:38665,50106:29028,50107:27809,50108:30473,50109:23186,50110:38209,50111:27599,50112:32654,50113:26151,50114:23504,50115:22969,50116:23194,50117:38376,50118:38391,50119:20204,50120:33804,50121:33945,50122:27308,50123:30431,50124:38192,50125:29467,50126:26790,50127:23391,50128:30511,50129:37274,50130:38753,50131:31964,50132:36855,50133:35868,50134:24357,50135:31859,50136:31192,50137:35269,50138:27852,50139:34588,50140:23494,50141:24130,50142:26825,50143:30496,50144:32501,50145:20885,50146:20813,50147:21193,50148:23081,50149:32517,50150:38754,50151:33495,50152:25551,50153:30596,50154:34256,50155:31186,50156:28218,50157:24217,50158:22937,50159:34065,50160:28781,50161:27665,50162:25279,50163:30399,50164:25935,50165:24751,50166:38397,50167:26126,50168:34719,50169:40483,50170:38125,50171:21517,50172:21629,50173:35884,50174:25720,50240:33088,50241:33089,50242:33090,50243:33091,50244:33092,50245:33093,50246:33095,50247:33097,50248:33101,50249:33102,50250:33103,50251:33106,50252:33110,50253:33111,50254:33112,50255:33115,50256:33116,50257:33117,50258:33118,50259:33119,50260:33121,50261:33122,50262:33123,50263:33124,50264:33126,50265:33128,50266:33130,50267:33131,50268:33132,50269:33135,50270:33138,50271:33139,50272:33141,50273:33142,50274:33143,50275:33144,50276:33153,50277:33155,50278:33156,50279:33157,50280:33158,50281:33159,50282:33161,50283:33163,50284:33164,50285:33165,50286:33166,50287:33168,50288:33170,50289:33171,50290:33172,50291:33173,50292:33174,50293:33175,50294:33177,50295:33178,50296:33182,50297:33183,50298:33184,50299:33185,50300:33186,50301:33188,50302:33189,50304:33191,50305:33193,50306:33195,50307:33196,50308:33197,50309:33198,50310:33199,50311:33200,50312:33201,50313:33202,50314:33204,50315:33205,50316:33206,50317:33207,50318:33208,50319:33209,50320:33212,50321:33213,50322:33214,50323:33215,50324:33220,50325:33221,50326:33223,50327:33224,50328:33225,50329:33227,50330:33229,50331:33230,50332:33231,50333:33232,50334:33233,50335:33234,50336:33235,50337:25721,50338:34321,50339:27169,50340:33180,50341:30952,50342:25705,50343:39764,50344:25273,50345:26411,50346:33707,50347:22696,50348:40664,50349:27819,50350:28448,50351:23518,50352:38476,50353:35851,50354:29279,50355:26576,50356:25287,50357:29281,50358:20137,50359:22982,50360:27597,50361:22675,50362:26286,50363:24149,50364:21215,50365:24917,50366:26408,50367:30446,50368:30566,50369:29287,50370:31302,50371:25343,50372:21738,50373:21584,50374:38048,50375:37027,50376:23068,50377:32435,50378:27670,50379:20035,50380:22902,50381:32784,50382:22856,50383:21335,50384:30007,50385:38590,50386:22218,50387:25376,50388:33041,50389:24700,50390:38393,50391:28118,50392:21602,50393:39297,50394:20869,50395:23273,50396:33021,50397:22958,50398:38675,50399:20522,50400:27877,50401:23612,50402:25311,50403:20320,50404:21311,50405:33147,50406:36870,50407:28346,50408:34091,50409:25288,50410:24180,50411:30910,50412:25781,50413:25467,50414:24565,50415:23064,50416:37247,50417:40479,50418:23615,50419:25423,50420:32834,50421:23421,50422:21870,50423:38218,50424:38221,50425:28037,50426:24744,50427:26592,50428:29406,50429:20957,50430:23425,50496:33236,50497:33237,50498:33238,50499:33239,50500:33240,50501:33241,50502:33242,50503:33243,50504:33244,50505:33245,50506:33246,50507:33247,50508:33248,50509:33249,50510:33250,50511:33252,50512:33253,50513:33254,50514:33256,50515:33257,50516:33259,50517:33262,50518:33263,50519:33264,50520:33265,50521:33266,50522:33269,50523:33270,50524:33271,50525:33272,50526:33273,50527:33274,50528:33277,50529:33279,50530:33283,50531:33287,50532:33288,50533:33289,50534:33290,50535:33291,50536:33294,50537:33295,50538:33297,50539:33299,50540:33301,50541:33302,50542:33303,50543:33304,50544:33305,50545:33306,50546:33309,50547:33312,50548:33316,50549:33317,50550:33318,50551:33319,50552:33321,50553:33326,50554:33330,50555:33338,50556:33340,50557:33341,50558:33343,50560:33344,50561:33345,50562:33346,50563:33347,50564:33349,50565:33350,50566:33352,50567:33354,50568:33356,50569:33357,50570:33358,50571:33360,50572:33361,50573:33362,50574:33363,50575:33364,50576:33365,50577:33366,50578:33367,50579:33369,50580:33371,50581:33372,50582:33373,50583:33374,50584:33376,50585:33377,50586:33378,50587:33379,50588:33380,50589:33381,50590:33382,50591:33383,50592:33385,50593:25319,50594:27870,50595:29275,50596:25197,50597:38062,50598:32445,50599:33043,50600:27987,50601:20892,50602:24324,50603:22900,50604:21162,50605:24594,50606:22899,50607:26262,50608:34384,50609:30111,50610:25386,50611:25062,50612:31983,50613:35834,50614:21734,50615:27431,50616:40485,50617:27572,50618:34261,50619:21589,50620:20598,50621:27812,50622:21866,50623:36276,50624:29228,50625:24085,50626:24597,50627:29750,50628:25293,50629:25490,50630:29260,50631:24472,50632:28227,50633:27966,50634:25856,50635:28504,50636:30424,50637:30928,50638:30460,50639:30036,50640:21028,50641:21467,50642:20051,50643:24222,50644:26049,50645:32810,50646:32982,50647:25243,50648:21638,50649:21032,50650:28846,50651:34957,50652:36305,50653:27873,50654:21624,50655:32986,50656:22521,50657:35060,50658:36180,50659:38506,50660:37197,50661:20329,50662:27803,50663:21943,50664:30406,50665:30768,50666:25256,50667:28921,50668:28558,50669:24429,50670:34028,50671:26842,50672:30844,50673:31735,50674:33192,50675:26379,50676:40527,50677:25447,50678:30896,50679:22383,50680:30738,50681:38713,50682:25209,50683:25259,50684:21128,50685:29749,50686:27607,50752:33386,50753:33387,50754:33388,50755:33389,50756:33393,50757:33397,50758:33398,50759:33399,50760:33400,50761:33403,50762:33404,50763:33408,50764:33409,50765:33411,50766:33413,50767:33414,50768:33415,50769:33417,50770:33420,50771:33424,50772:33427,50773:33428,50774:33429,50775:33430,50776:33434,50777:33435,50778:33438,50779:33440,50780:33442,50781:33443,50782:33447,50783:33458,50784:33461,50785:33462,50786:33466,50787:33467,50788:33468,50789:33471,50790:33472,50791:33474,50792:33475,50793:33477,50794:33478,50795:33481,50796:33488,50797:33494,50798:33497,50799:33498,50800:33501,50801:33506,50802:33511,50803:33512,50804:33513,50805:33514,50806:33516,50807:33517,50808:33518,50809:33520,50810:33522,50811:33523,50812:33525,50813:33526,50814:33528,50816:33530,50817:33532,50818:33533,50819:33534,50820:33535,50821:33536,50822:33546,50823:33547,50824:33549,50825:33552,50826:33554,50827:33555,50828:33558,50829:33560,50830:33561,50831:33565,50832:33566,50833:33567,50834:33568,50835:33569,50836:33570,50837:33571,50838:33572,50839:33573,50840:33574,50841:33577,50842:33578,50843:33582,50844:33584,50845:33586,50846:33591,50847:33595,50848:33597,50849:21860,50850:33086,50851:30130,50852:30382,50853:21305,50854:30174,50855:20731,50856:23617,50857:35692,50858:31687,50859:20559,50860:29255,50861:39575,50862:39128,50863:28418,50864:29922,50865:31080,50866:25735,50867:30629,50868:25340,50869:39057,50870:36139,50871:21697,50872:32856,50873:20050,50874:22378,50875:33529,50876:33805,50877:24179,50878:20973,50879:29942,50880:35780,50881:23631,50882:22369,50883:27900,50884:39047,50885:23110,50886:30772,50887:39748,50888:36843,50889:31893,50890:21078,50891:25169,50892:38138,50893:20166,50894:33670,50895:33889,50896:33769,50897:33970,50898:22484,50899:26420,50900:22275,50901:26222,50902:28006,50903:35889,50904:26333,50905:28689,50906:26399,50907:27450,50908:26646,50909:25114,50910:22971,50911:19971,50912:20932,50913:28422,50914:26578,50915:27791,50916:20854,50917:26827,50918:22855,50919:27495,50920:30054,50921:23822,50922:33040,50923:40784,50924:26071,50925:31048,50926:31041,50927:39569,50928:36215,50929:23682,50930:20062,50931:20225,50932:21551,50933:22865,50934:30732,50935:22120,50936:27668,50937:36804,50938:24323,50939:27773,50940:27875,50941:35755,50942:25488,51008:33598,51009:33599,51010:33601,51011:33602,51012:33604,51013:33605,51014:33608,51015:33610,51016:33611,51017:33612,51018:33613,51019:33614,51020:33619,51021:33621,51022:33622,51023:33623,51024:33624,51025:33625,51026:33629,51027:33634,51028:33648,51029:33649,51030:33650,51031:33651,51032:33652,51033:33653,51034:33654,51035:33657,51036:33658,51037:33662,51038:33663,51039:33664,51040:33665,51041:33666,51042:33667,51043:33668,51044:33671,51045:33672,51046:33674,51047:33675,51048:33676,51049:33677,51050:33679,51051:33680,51052:33681,51053:33684,51054:33685,51055:33686,51056:33687,51057:33689,51058:33690,51059:33693,51060:33695,51061:33697,51062:33698,51063:33699,51064:33700,51065:33701,51066:33702,51067:33703,51068:33708,51069:33709,51070:33710,51072:33711,51073:33717,51074:33723,51075:33726,51076:33727,51077:33730,51078:33731,51079:33732,51080:33734,51081:33736,51082:33737,51083:33739,51084:33741,51085:33742,51086:33744,51087:33745,51088:33746,51089:33747,51090:33749,51091:33751,51092:33753,51093:33754,51094:33755,51095:33758,51096:33762,51097:33763,51098:33764,51099:33766,51100:33767,51101:33768,51102:33771,51103:33772,51104:33773,51105:24688,51106:27965,51107:29301,51108:25190,51109:38030,51110:38085,51111:21315,51112:36801,51113:31614,51114:20191,51115:35878,51116:20094,51117:40660,51118:38065,51119:38067,51120:21069,51121:28508,51122:36963,51123:27973,51124:35892,51125:22545,51126:23884,51127:27424,51128:27465,51129:26538,51130:21595,51131:33108,51132:32652,51133:22681,51134:34103,51135:24378,51136:25250,51137:27207,51138:38201,51139:25970,51140:24708,51141:26725,51142:30631,51143:20052,51144:20392,51145:24039,51146:38808,51147:25772,51148:32728,51149:23789,51150:20431,51151:31373,51152:20999,51153:33540,51154:19988,51155:24623,51156:31363,51157:38054,51158:20405,51159:20146,51160:31206,51161:29748,51162:21220,51163:33465,51164:25810,51165:31165,51166:23517,51167:27777,51168:38738,51169:36731,51170:27682,51171:20542,51172:21375,51173:28165,51174:25806,51175:26228,51176:27696,51177:24773,51178:39031,51179:35831,51180:24198,51181:29756,51182:31351,51183:31179,51184:19992,51185:37041,51186:29699,51187:27714,51188:22234,51189:37195,51190:27845,51191:36235,51192:21306,51193:34502,51194:26354,51195:36527,51196:23624,51197:39537,51198:28192,51264:33774,51265:33775,51266:33779,51267:33780,51268:33781,51269:33782,51270:33783,51271:33786,51272:33787,51273:33788,51274:33790,51275:33791,51276:33792,51277:33794,51278:33797,51279:33799,51280:33800,51281:33801,51282:33802,51283:33808,51284:33810,51285:33811,51286:33812,51287:33813,51288:33814,51289:33815,51290:33817,51291:33818,51292:33819,51293:33822,51294:33823,51295:33824,51296:33825,51297:33826,51298:33827,51299:33833,51300:33834,51301:33835,51302:33836,51303:33837,51304:33838,51305:33839,51306:33840,51307:33842,51308:33843,51309:33844,51310:33845,51311:33846,51312:33847,51313:33849,51314:33850,51315:33851,51316:33854,51317:33855,51318:33856,51319:33857,51320:33858,51321:33859,51322:33860,51323:33861,51324:33863,51325:33864,51326:33865,51328:33866,51329:33867,51330:33868,51331:33869,51332:33870,51333:33871,51334:33872,51335:33874,51336:33875,51337:33876,51338:33877,51339:33878,51340:33880,51341:33885,51342:33886,51343:33887,51344:33888,51345:33890,51346:33892,51347:33893,51348:33894,51349:33895,51350:33896,51351:33898,51352:33902,51353:33903,51354:33904,51355:33906,51356:33908,51357:33911,51358:33913,51359:33915,51360:33916,51361:21462,51362:23094,51363:40843,51364:36259,51365:21435,51366:22280,51367:39079,51368:26435,51369:37275,51370:27849,51371:20840,51372:30154,51373:25331,51374:29356,51375:21048,51376:21149,51377:32570,51378:28820,51379:30264,51380:21364,51381:40522,51382:27063,51383:30830,51384:38592,51385:35033,51386:32676,51387:28982,51388:29123,51389:20873,51390:26579,51391:29924,51392:22756,51393:25880,51394:22199,51395:35753,51396:39286,51397:25200,51398:32469,51399:24825,51400:28909,51401:22764,51402:20161,51403:20154,51404:24525,51405:38887,51406:20219,51407:35748,51408:20995,51409:22922,51410:32427,51411:25172,51412:20173,51413:26085,51414:25102,51415:33592,51416:33993,51417:33635,51418:34701,51419:29076,51420:28342,51421:23481,51422:32466,51423:20887,51424:25545,51425:26580,51426:32905,51427:33593,51428:34837,51429:20754,51430:23418,51431:22914,51432:36785,51433:20083,51434:27741,51435:20837,51436:35109,51437:36719,51438:38446,51439:34122,51440:29790,51441:38160,51442:38384,51443:28070,51444:33509,51445:24369,51446:25746,51447:27922,51448:33832,51449:33134,51450:40131,51451:22622,51452:36187,51453:19977,51454:21441,51520:33917,51521:33918,51522:33919,51523:33920,51524:33921,51525:33923,51526:33924,51527:33925,51528:33926,51529:33930,51530:33933,51531:33935,51532:33936,51533:33937,51534:33938,51535:33939,51536:33940,51537:33941,51538:33942,51539:33944,51540:33946,51541:33947,51542:33949,51543:33950,51544:33951,51545:33952,51546:33954,51547:33955,51548:33956,51549:33957,51550:33958,51551:33959,51552:33960,51553:33961,51554:33962,51555:33963,51556:33964,51557:33965,51558:33966,51559:33968,51560:33969,51561:33971,51562:33973,51563:33974,51564:33975,51565:33979,51566:33980,51567:33982,51568:33984,51569:33986,51570:33987,51571:33989,51572:33990,51573:33991,51574:33992,51575:33995,51576:33996,51577:33998,51578:33999,51579:34002,51580:34004,51581:34005,51582:34007,51584:34008,51585:34009,51586:34010,51587:34011,51588:34012,51589:34014,51590:34017,51591:34018,51592:34020,51593:34023,51594:34024,51595:34025,51596:34026,51597:34027,51598:34029,51599:34030,51600:34031,51601:34033,51602:34034,51603:34035,51604:34036,51605:34037,51606:34038,51607:34039,51608:34040,51609:34041,51610:34042,51611:34043,51612:34045,51613:34046,51614:34048,51615:34049,51616:34050,51617:20254,51618:25955,51619:26705,51620:21971,51621:20007,51622:25620,51623:39578,51624:25195,51625:23234,51626:29791,51627:33394,51628:28073,51629:26862,51630:20711,51631:33678,51632:30722,51633:26432,51634:21049,51635:27801,51636:32433,51637:20667,51638:21861,51639:29022,51640:31579,51641:26194,51642:29642,51643:33515,51644:26441,51645:23665,51646:21024,51647:29053,51648:34923,51649:38378,51650:38485,51651:25797,51652:36193,51653:33203,51654:21892,51655:27733,51656:25159,51657:32558,51658:22674,51659:20260,51660:21830,51661:36175,51662:26188,51663:19978,51664:23578,51665:35059,51666:26786,51667:25422,51668:31245,51669:28903,51670:33421,51671:21242,51672:38902,51673:23569,51674:21736,51675:37045,51676:32461,51677:22882,51678:36170,51679:34503,51680:33292,51681:33293,51682:36198,51683:25668,51684:23556,51685:24913,51686:28041,51687:31038,51688:35774,51689:30775,51690:30003,51691:21627,51692:20280,51693:36523,51694:28145,51695:23072,51696:32453,51697:31070,51698:27784,51699:23457,51700:23158,51701:29978,51702:32958,51703:24910,51704:28183,51705:22768,51706:29983,51707:29989,51708:29298,51709:21319,51710:32499,51776:34051,51777:34052,51778:34053,51779:34054,51780:34055,51781:34056,51782:34057,51783:34058,51784:34059,51785:34061,51786:34062,51787:34063,51788:34064,51789:34066,51790:34068,51791:34069,51792:34070,51793:34072,51794:34073,51795:34075,51796:34076,51797:34077,51798:34078,51799:34080,51800:34082,51801:34083,51802:34084,51803:34085,51804:34086,51805:34087,51806:34088,51807:34089,51808:34090,51809:34093,51810:34094,51811:34095,51812:34096,51813:34097,51814:34098,51815:34099,51816:34100,51817:34101,51818:34102,51819:34110,51820:34111,51821:34112,51822:34113,51823:34114,51824:34116,51825:34117,51826:34118,51827:34119,51828:34123,51829:34124,51830:34125,51831:34126,51832:34127,51833:34128,51834:34129,51835:34130,51836:34131,51837:34132,51838:34133,51840:34135,51841:34136,51842:34138,51843:34139,51844:34140,51845:34141,51846:34143,51847:34144,51848:34145,51849:34146,51850:34147,51851:34149,51852:34150,51853:34151,51854:34153,51855:34154,51856:34155,51857:34156,51858:34157,51859:34158,51860:34159,51861:34160,51862:34161,51863:34163,51864:34165,51865:34166,51866:34167,51867:34168,51868:34172,51869:34173,51870:34175,51871:34176,51872:34177,51873:30465,51874:30427,51875:21097,51876:32988,51877:22307,51878:24072,51879:22833,51880:29422,51881:26045,51882:28287,51883:35799,51884:23608,51885:34417,51886:21313,51887:30707,51888:25342,51889:26102,51890:20160,51891:39135,51892:34432,51893:23454,51894:35782,51895:21490,51896:30690,51897:20351,51898:23630,51899:39542,51900:22987,51901:24335,51902:31034,51903:22763,51904:19990,51905:26623,51906:20107,51907:25325,51908:35475,51909:36893,51910:21183,51911:26159,51912:21980,51913:22124,51914:36866,51915:20181,51916:20365,51917:37322,51918:39280,51919:27663,51920:24066,51921:24643,51922:23460,51923:35270,51924:35797,51925:25910,51926:25163,51927:39318,51928:23432,51929:23551,51930:25480,51931:21806,51932:21463,51933:30246,51934:20861,51935:34092,51936:26530,51937:26803,51938:27530,51939:25234,51940:36755,51941:21460,51942:33298,51943:28113,51944:30095,51945:20070,51946:36174,51947:23408,51948:29087,51949:34223,51950:26257,51951:26329,51952:32626,51953:34560,51954:40653,51955:40736,51956:23646,51957:26415,51958:36848,51959:26641,51960:26463,51961:25101,51962:31446,51963:22661,51964:24246,51965:25968,51966:28465,52032:34178,52033:34179,52034:34182,52035:34184,52036:34185,52037:34186,52038:34187,52039:34188,52040:34189,52041:34190,52042:34192,52043:34193,52044:34194,52045:34195,52046:34196,52047:34197,52048:34198,52049:34199,52050:34200,52051:34201,52052:34202,52053:34205,52054:34206,52055:34207,52056:34208,52057:34209,52058:34210,52059:34211,52060:34213,52061:34214,52062:34215,52063:34217,52064:34219,52065:34220,52066:34221,52067:34225,52068:34226,52069:34227,52070:34228,52071:34229,52072:34230,52073:34232,52074:34234,52075:34235,52076:34236,52077:34237,52078:34238,52079:34239,52080:34240,52081:34242,52082:34243,52083:34244,52084:34245,52085:34246,52086:34247,52087:34248,52088:34250,52089:34251,52090:34252,52091:34253,52092:34254,52093:34257,52094:34258,52096:34260,52097:34262,52098:34263,52099:34264,52100:34265,52101:34266,52102:34267,52103:34269,52104:34270,52105:34271,52106:34272,52107:34273,52108:34274,52109:34275,52110:34277,52111:34278,52112:34279,52113:34280,52114:34282,52115:34283,52116:34284,52117:34285,52118:34286,52119:34287,52120:34288,52121:34289,52122:34290,52123:34291,52124:34292,52125:34293,52126:34294,52127:34295,52128:34296,52129:24661,52130:21047,52131:32781,52132:25684,52133:34928,52134:29993,52135:24069,52136:26643,52137:25332,52138:38684,52139:21452,52140:29245,52141:35841,52142:27700,52143:30561,52144:31246,52145:21550,52146:30636,52147:39034,52148:33308,52149:35828,52150:30805,52151:26388,52152:28865,52153:26031,52154:25749,52155:22070,52156:24605,52157:31169,52158:21496,52159:19997,52160:27515,52161:32902,52162:23546,52163:21987,52164:22235,52165:20282,52166:20284,52167:39282,52168:24051,52169:26494,52170:32824,52171:24578,52172:39042,52173:36865,52174:23435,52175:35772,52176:35829,52177:25628,52178:33368,52179:25822,52180:22013,52181:33487,52182:37221,52183:20439,52184:32032,52185:36895,52186:31903,52187:20723,52188:22609,52189:28335,52190:23487,52191:35785,52192:32899,52193:37240,52194:33948,52195:31639,52196:34429,52197:38539,52198:38543,52199:32485,52200:39635,52201:30862,52202:23681,52203:31319,52204:36930,52205:38567,52206:31071,52207:23385,52208:25439,52209:31499,52210:34001,52211:26797,52212:21766,52213:32553,52214:29712,52215:32034,52216:38145,52217:25152,52218:22604,52219:20182,52220:23427,52221:22905,52222:22612,52288:34297,52289:34298,52290:34300,52291:34301,52292:34302,52293:34304,52294:34305,52295:34306,52296:34307,52297:34308,52298:34310,52299:34311,52300:34312,52301:34313,52302:34314,52303:34315,52304:34316,52305:34317,52306:34318,52307:34319,52308:34320,52309:34322,52310:34323,52311:34324,52312:34325,52313:34327,52314:34328,52315:34329,52316:34330,52317:34331,52318:34332,52319:34333,52320:34334,52321:34335,52322:34336,52323:34337,52324:34338,52325:34339,52326:34340,52327:34341,52328:34342,52329:34344,52330:34346,52331:34347,52332:34348,52333:34349,52334:34350,52335:34351,52336:34352,52337:34353,52338:34354,52339:34355,52340:34356,52341:34357,52342:34358,52343:34359,52344:34361,52345:34362,52346:34363,52347:34365,52348:34366,52349:34367,52350:34368,52352:34369,52353:34370,52354:34371,52355:34372,52356:34373,52357:34374,52358:34375,52359:34376,52360:34377,52361:34378,52362:34379,52363:34380,52364:34386,52365:34387,52366:34389,52367:34390,52368:34391,52369:34392,52370:34393,52371:34395,52372:34396,52373:34397,52374:34399,52375:34400,52376:34401,52377:34403,52378:34404,52379:34405,52380:34406,52381:34407,52382:34408,52383:34409,52384:34410,52385:29549,52386:25374,52387:36427,52388:36367,52389:32974,52390:33492,52391:25260,52392:21488,52393:27888,52394:37214,52395:22826,52396:24577,52397:27760,52398:22349,52399:25674,52400:36138,52401:30251,52402:28393,52403:22363,52404:27264,52405:30192,52406:28525,52407:35885,52408:35848,52409:22374,52410:27631,52411:34962,52412:30899,52413:25506,52414:21497,52415:28845,52416:27748,52417:22616,52418:25642,52419:22530,52420:26848,52421:33179,52422:21776,52423:31958,52424:20504,52425:36538,52426:28108,52427:36255,52428:28907,52429:25487,52430:28059,52431:28372,52432:32486,52433:33796,52434:26691,52435:36867,52436:28120,52437:38518,52438:35752,52439:22871,52440:29305,52441:34276,52442:33150,52443:30140,52444:35466,52445:26799,52446:21076,52447:36386,52448:38161,52449:25552,52450:39064,52451:36420,52452:21884,52453:20307,52454:26367,52455:22159,52456:24789,52457:28053,52458:21059,52459:23625,52460:22825,52461:28155,52462:22635,52463:30000,52464:29980,52465:24684,52466:33300,52467:33094,52468:25361,52469:26465,52470:36834,52471:30522,52472:36339,52473:36148,52474:38081,52475:24086,52476:21381,52477:21548,52478:28867,52544:34413,52545:34415,52546:34416,52547:34418,52548:34419,52549:34420,52550:34421,52551:34422,52552:34423,52553:34424,52554:34435,52555:34436,52556:34437,52557:34438,52558:34439,52559:34440,52560:34441,52561:34446,52562:34447,52563:34448,52564:34449,52565:34450,52566:34452,52567:34454,52568:34455,52569:34456,52570:34457,52571:34458,52572:34459,52573:34462,52574:34463,52575:34464,52576:34465,52577:34466,52578:34469,52579:34470,52580:34475,52581:34477,52582:34478,52583:34482,52584:34483,52585:34487,52586:34488,52587:34489,52588:34491,52589:34492,52590:34493,52591:34494,52592:34495,52593:34497,52594:34498,52595:34499,52596:34501,52597:34504,52598:34508,52599:34509,52600:34514,52601:34515,52602:34517,52603:34518,52604:34519,52605:34522,52606:34524,52608:34525,52609:34528,52610:34529,52611:34530,52612:34531,52613:34533,52614:34534,52615:34535,52616:34536,52617:34538,52618:34539,52619:34540,52620:34543,52621:34549,52622:34550,52623:34551,52624:34554,52625:34555,52626:34556,52627:34557,52628:34559,52629:34561,52630:34564,52631:34565,52632:34566,52633:34571,52634:34572,52635:34574,52636:34575,52637:34576,52638:34577,52639:34580,52640:34582,52641:27712,52642:24311,52643:20572,52644:20141,52645:24237,52646:25402,52647:33351,52648:36890,52649:26704,52650:37230,52651:30643,52652:21516,52653:38108,52654:24420,52655:31461,52656:26742,52657:25413,52658:31570,52659:32479,52660:30171,52661:20599,52662:25237,52663:22836,52664:36879,52665:20984,52666:31171,52667:31361,52668:22270,52669:24466,52670:36884,52671:28034,52672:23648,52673:22303,52674:21520,52675:20820,52676:28237,52677:22242,52678:25512,52679:39059,52680:33151,52681:34581,52682:35114,52683:36864,52684:21534,52685:23663,52686:33216,52687:25302,52688:25176,52689:33073,52690:40501,52691:38464,52692:39534,52693:39548,52694:26925,52695:22949,52696:25299,52697:21822,52698:25366,52699:21703,52700:34521,52701:27964,52702:23043,52703:29926,52704:34972,52705:27498,52706:22806,52707:35916,52708:24367,52709:28286,52710:29609,52711:39037,52712:20024,52713:28919,52714:23436,52715:30871,52716:25405,52717:26202,52718:30358,52719:24779,52720:23451,52721:23113,52722:19975,52723:33109,52724:27754,52725:29579,52726:20129,52727:26505,52728:32593,52729:24448,52730:26106,52731:26395,52732:24536,52733:22916,52734:23041,52800:34585,52801:34587,52802:34589,52803:34591,52804:34592,52805:34596,52806:34598,52807:34599,52808:34600,52809:34602,52810:34603,52811:34604,52812:34605,52813:34607,52814:34608,52815:34610,52816:34611,52817:34613,52818:34614,52819:34616,52820:34617,52821:34618,52822:34620,52823:34621,52824:34624,52825:34625,52826:34626,52827:34627,52828:34628,52829:34629,52830:34630,52831:34634,52832:34635,52833:34637,52834:34639,52835:34640,52836:34641,52837:34642,52838:34644,52839:34645,52840:34646,52841:34648,52842:34650,52843:34651,52844:34652,52845:34653,52846:34654,52847:34655,52848:34657,52849:34658,52850:34662,52851:34663,52852:34664,52853:34665,52854:34666,52855:34667,52856:34668,52857:34669,52858:34671,52859:34673,52860:34674,52861:34675,52862:34677,52864:34679,52865:34680,52866:34681,52867:34682,52868:34687,52869:34688,52870:34689,52871:34692,52872:34694,52873:34695,52874:34697,52875:34698,52876:34700,52877:34702,52878:34703,52879:34704,52880:34705,52881:34706,52882:34708,52883:34709,52884:34710,52885:34712,52886:34713,52887:34714,52888:34715,52889:34716,52890:34717,52891:34718,52892:34720,52893:34721,52894:34722,52895:34723,52896:34724,52897:24013,52898:24494,52899:21361,52900:38886,52901:36829,52902:26693,52903:22260,52904:21807,52905:24799,52906:20026,52907:28493,52908:32500,52909:33479,52910:33806,52911:22996,52912:20255,52913:20266,52914:23614,52915:32428,52916:26410,52917:34074,52918:21619,52919:30031,52920:32963,52921:21890,52922:39759,52923:20301,52924:28205,52925:35859,52926:23561,52927:24944,52928:21355,52929:30239,52930:28201,52931:34442,52932:25991,52933:38395,52934:32441,52935:21563,52936:31283,52937:32010,52938:38382,52939:21985,52940:32705,52941:29934,52942:25373,52943:34583,52944:28065,52945:31389,52946:25105,52947:26017,52948:21351,52949:25569,52950:27779,52951:24043,52952:21596,52953:38056,52954:20044,52955:27745,52956:35820,52957:23627,52958:26080,52959:33436,52960:26791,52961:21566,52962:21556,52963:27595,52964:27494,52965:20116,52966:25410,52967:21320,52968:33310,52969:20237,52970:20398,52971:22366,52972:25098,52973:38654,52974:26212,52975:29289,52976:21247,52977:21153,52978:24735,52979:35823,52980:26132,52981:29081,52982:26512,52983:35199,52984:30802,52985:30717,52986:26224,52987:22075,52988:21560,52989:38177,52990:29306,53056:34725,53057:34726,53058:34727,53059:34729,53060:34730,53061:34734,53062:34736,53063:34737,53064:34738,53065:34740,53066:34742,53067:34743,53068:34744,53069:34745,53070:34747,53071:34748,53072:34750,53073:34751,53074:34753,53075:34754,53076:34755,53077:34756,53078:34757,53079:34759,53080:34760,53081:34761,53082:34764,53083:34765,53084:34766,53085:34767,53086:34768,53087:34772,53088:34773,53089:34774,53090:34775,53091:34776,53092:34777,53093:34778,53094:34780,53095:34781,53096:34782,53097:34783,53098:34785,53099:34786,53100:34787,53101:34788,53102:34790,53103:34791,53104:34792,53105:34793,53106:34795,53107:34796,53108:34797,53109:34799,53110:34800,53111:34801,53112:34802,53113:34803,53114:34804,53115:34805,53116:34806,53117:34807,53118:34808,53120:34810,53121:34811,53122:34812,53123:34813,53124:34815,53125:34816,53126:34817,53127:34818,53128:34820,53129:34821,53130:34822,53131:34823,53132:34824,53133:34825,53134:34827,53135:34828,53136:34829,53137:34830,53138:34831,53139:34832,53140:34833,53141:34834,53142:34836,53143:34839,53144:34840,53145:34841,53146:34842,53147:34844,53148:34845,53149:34846,53150:34847,53151:34848,53152:34851,53153:31232,53154:24687,53155:24076,53156:24713,53157:33181,53158:22805,53159:24796,53160:29060,53161:28911,53162:28330,53163:27728,53164:29312,53165:27268,53166:34989,53167:24109,53168:20064,53169:23219,53170:21916,53171:38115,53172:27927,53173:31995,53174:38553,53175:25103,53176:32454,53177:30606,53178:34430,53179:21283,53180:38686,53181:36758,53182:26247,53183:23777,53184:20384,53185:29421,53186:19979,53187:21414,53188:22799,53189:21523,53190:25472,53191:38184,53192:20808,53193:20185,53194:40092,53195:32420,53196:21688,53197:36132,53198:34900,53199:33335,53200:38386,53201:28046,53202:24358,53203:23244,53204:26174,53205:38505,53206:29616,53207:29486,53208:21439,53209:33146,53210:39301,53211:32673,53212:23466,53213:38519,53214:38480,53215:32447,53216:30456,53217:21410,53218:38262,53219:39321,53220:31665,53221:35140,53222:28248,53223:20065,53224:32724,53225:31077,53226:35814,53227:24819,53228:21709,53229:20139,53230:39033,53231:24055,53232:27233,53233:20687,53234:21521,53235:35937,53236:33831,53237:30813,53238:38660,53239:21066,53240:21742,53241:22179,53242:38144,53243:28040,53244:23477,53245:28102,53246:26195,53312:34852,53313:34853,53314:34854,53315:34855,53316:34856,53317:34857,53318:34858,53319:34859,53320:34860,53321:34861,53322:34862,53323:34863,53324:34864,53325:34865,53326:34867,53327:34868,53328:34869,53329:34870,53330:34871,53331:34872,53332:34874,53333:34875,53334:34877,53335:34878,53336:34879,53337:34881,53338:34882,53339:34883,53340:34886,53341:34887,53342:34888,53343:34889,53344:34890,53345:34891,53346:34894,53347:34895,53348:34896,53349:34897,53350:34898,53351:34899,53352:34901,53353:34902,53354:34904,53355:34906,53356:34907,53357:34908,53358:34909,53359:34910,53360:34911,53361:34912,53362:34918,53363:34919,53364:34922,53365:34925,53366:34927,53367:34929,53368:34931,53369:34932,53370:34933,53371:34934,53372:34936,53373:34937,53374:34938,53376:34939,53377:34940,53378:34944,53379:34947,53380:34950,53381:34951,53382:34953,53383:34954,53384:34956,53385:34958,53386:34959,53387:34960,53388:34961,53389:34963,53390:34964,53391:34965,53392:34967,53393:34968,53394:34969,53395:34970,53396:34971,53397:34973,53398:34974,53399:34975,53400:34976,53401:34977,53402:34979,53403:34981,53404:34982,53405:34983,53406:34984,53407:34985,53408:34986,53409:23567,53410:23389,53411:26657,53412:32918,53413:21880,53414:31505,53415:25928,53416:26964,53417:20123,53418:27463,53419:34638,53420:38795,53421:21327,53422:25375,53423:25658,53424:37034,53425:26012,53426:32961,53427:35856,53428:20889,53429:26800,53430:21368,53431:34809,53432:25032,53433:27844,53434:27899,53435:35874,53436:23633,53437:34218,53438:33455,53439:38156,53440:27427,53441:36763,53442:26032,53443:24571,53444:24515,53445:20449,53446:34885,53447:26143,53448:33125,53449:29481,53450:24826,53451:20852,53452:21009,53453:22411,53454:24418,53455:37026,53456:34892,53457:37266,53458:24184,53459:26447,53460:24615,53461:22995,53462:20804,53463:20982,53464:33016,53465:21256,53466:27769,53467:38596,53468:29066,53469:20241,53470:20462,53471:32670,53472:26429,53473:21957,53474:38152,53475:31168,53476:34966,53477:32483,53478:22687,53479:25100,53480:38656,53481:34394,53482:22040,53483:39035,53484:24464,53485:35768,53486:33988,53487:37207,53488:21465,53489:26093,53490:24207,53491:30044,53492:24676,53493:32110,53494:23167,53495:32490,53496:32493,53497:36713,53498:21927,53499:23459,53500:24748,53501:26059,53502:29572,53568:34988,53569:34990,53570:34991,53571:34992,53572:34994,53573:34995,53574:34996,53575:34997,53576:34998,53577:35000,53578:35001,53579:35002,53580:35003,53581:35005,53582:35006,53583:35007,53584:35008,53585:35011,53586:35012,53587:35015,53588:35016,53589:35018,53590:35019,53591:35020,53592:35021,53593:35023,53594:35024,53595:35025,53596:35027,53597:35030,53598:35031,53599:35034,53600:35035,53601:35036,53602:35037,53603:35038,53604:35040,53605:35041,53606:35046,53607:35047,53608:35049,53609:35050,53610:35051,53611:35052,53612:35053,53613:35054,53614:35055,53615:35058,53616:35061,53617:35062,53618:35063,53619:35066,53620:35067,53621:35069,53622:35071,53623:35072,53624:35073,53625:35075,53626:35076,53627:35077,53628:35078,53629:35079,53630:35080,53632:35081,53633:35083,53634:35084,53635:35085,53636:35086,53637:35087,53638:35089,53639:35092,53640:35093,53641:35094,53642:35095,53643:35096,53644:35100,53645:35101,53646:35102,53647:35103,53648:35104,53649:35106,53650:35107,53651:35108,53652:35110,53653:35111,53654:35112,53655:35113,53656:35116,53657:35117,53658:35118,53659:35119,53660:35121,53661:35122,53662:35123,53663:35125,53664:35127,53665:36873,53666:30307,53667:30505,53668:32474,53669:38772,53670:34203,53671:23398,53672:31348,53673:38634,53674:34880,53675:21195,53676:29071,53677:24490,53678:26092,53679:35810,53680:23547,53681:39535,53682:24033,53683:27529,53684:27739,53685:35757,53686:35759,53687:36874,53688:36805,53689:21387,53690:25276,53691:40486,53692:40493,53693:21568,53694:20011,53695:33469,53696:29273,53697:34460,53698:23830,53699:34905,53700:28079,53701:38597,53702:21713,53703:20122,53704:35766,53705:28937,53706:21693,53707:38409,53708:28895,53709:28153,53710:30416,53711:20005,53712:30740,53713:34578,53714:23721,53715:24310,53716:35328,53717:39068,53718:38414,53719:28814,53720:27839,53721:22852,53722:25513,53723:30524,53724:34893,53725:28436,53726:33395,53727:22576,53728:29141,53729:21388,53730:30746,53731:38593,53732:21761,53733:24422,53734:28976,53735:23476,53736:35866,53737:39564,53738:27523,53739:22830,53740:40495,53741:31207,53742:26472,53743:25196,53744:20335,53745:30113,53746:32650,53747:27915,53748:38451,53749:27687,53750:20208,53751:30162,53752:20859,53753:26679,53754:28478,53755:36992,53756:33136,53757:22934,53758:29814,53824:35128,53825:35129,53826:35130,53827:35131,53828:35132,53829:35133,53830:35134,53831:35135,53832:35136,53833:35138,53834:35139,53835:35141,53836:35142,53837:35143,53838:35144,53839:35145,53840:35146,53841:35147,53842:35148,53843:35149,53844:35150,53845:35151,53846:35152,53847:35153,53848:35154,53849:35155,53850:35156,53851:35157,53852:35158,53853:35159,53854:35160,53855:35161,53856:35162,53857:35163,53858:35164,53859:35165,53860:35168,53861:35169,53862:35170,53863:35171,53864:35172,53865:35173,53866:35175,53867:35176,53868:35177,53869:35178,53870:35179,53871:35180,53872:35181,53873:35182,53874:35183,53875:35184,53876:35185,53877:35186,53878:35187,53879:35188,53880:35189,53881:35190,53882:35191,53883:35192,53884:35193,53885:35194,53886:35196,53888:35197,53889:35198,53890:35200,53891:35202,53892:35204,53893:35205,53894:35207,53895:35208,53896:35209,53897:35210,53898:35211,53899:35212,53900:35213,53901:35214,53902:35215,53903:35216,53904:35217,53905:35218,53906:35219,53907:35220,53908:35221,53909:35222,53910:35223,53911:35224,53912:35225,53913:35226,53914:35227,53915:35228,53916:35229,53917:35230,53918:35231,53919:35232,53920:35233,53921:25671,53922:23591,53923:36965,53924:31377,53925:35875,53926:23002,53927:21676,53928:33280,53929:33647,53930:35201,53931:32768,53932:26928,53933:22094,53934:32822,53935:29239,53936:37326,53937:20918,53938:20063,53939:39029,53940:25494,53941:19994,53942:21494,53943:26355,53944:33099,53945:22812,53946:28082,53947:19968,53948:22777,53949:21307,53950:25558,53951:38129,53952:20381,53953:20234,53954:34915,53955:39056,53956:22839,53957:36951,53958:31227,53959:20202,53960:33008,53961:30097,53962:27778,53963:23452,53964:23016,53965:24413,53966:26885,53967:34433,53968:20506,53969:24050,53970:20057,53971:30691,53972:20197,53973:33402,53974:25233,53975:26131,53976:37009,53977:23673,53978:20159,53979:24441,53980:33222,53981:36920,53982:32900,53983:30123,53984:20134,53985:35028,53986:24847,53987:27589,53988:24518,53989:20041,53990:30410,53991:28322,53992:35811,53993:35758,53994:35850,53995:35793,53996:24322,53997:32764,53998:32716,53999:32462,54000:33589,54001:33643,54002:22240,54003:27575,54004:38899,54005:38452,54006:23035,54007:21535,54008:38134,54009:28139,54010:23493,54011:39278,54012:23609,54013:24341,54014:38544,54080:35234,54081:35235,54082:35236,54083:35237,54084:35238,54085:35239,54086:35240,54087:35241,54088:35242,54089:35243,54090:35244,54091:35245,54092:35246,54093:35247,54094:35248,54095:35249,54096:35250,54097:35251,54098:35252,54099:35253,54100:35254,54101:35255,54102:35256,54103:35257,54104:35258,54105:35259,54106:35260,54107:35261,54108:35262,54109:35263,54110:35264,54111:35267,54112:35277,54113:35283,54114:35284,54115:35285,54116:35287,54117:35288,54118:35289,54119:35291,54120:35293,54121:35295,54122:35296,54123:35297,54124:35298,54125:35300,54126:35303,54127:35304,54128:35305,54129:35306,54130:35308,54131:35309,54132:35310,54133:35312,54134:35313,54135:35314,54136:35316,54137:35317,54138:35318,54139:35319,54140:35320,54141:35321,54142:35322,54144:35323,54145:35324,54146:35325,54147:35326,54148:35327,54149:35329,54150:35330,54151:35331,54152:35332,54153:35333,54154:35334,54155:35336,54156:35337,54157:35338,54158:35339,54159:35340,54160:35341,54161:35342,54162:35343,54163:35344,54164:35345,54165:35346,54166:35347,54167:35348,54168:35349,54169:35350,54170:35351,54171:35352,54172:35353,54173:35354,54174:35355,54175:35356,54176:35357,54177:21360,54178:33521,54179:27185,54180:23156,54181:40560,54182:24212,54183:32552,54184:33721,54185:33828,54186:33829,54187:33639,54188:34631,54189:36814,54190:36194,54191:30408,54192:24433,54193:39062,54194:30828,54195:26144,54196:21727,54197:25317,54198:20323,54199:33219,54200:30152,54201:24248,54202:38605,54203:36362,54204:34553,54205:21647,54206:27891,54207:28044,54208:27704,54209:24703,54210:21191,54211:29992,54212:24189,54213:20248,54214:24736,54215:24551,54216:23588,54217:30001,54218:37038,54219:38080,54220:29369,54221:27833,54222:28216,54223:37193,54224:26377,54225:21451,54226:21491,54227:20305,54228:37321,54229:35825,54230:21448,54231:24188,54232:36802,54233:28132,54234:20110,54235:30402,54236:27014,54237:34398,54238:24858,54239:33286,54240:20313,54241:20446,54242:36926,54243:40060,54244:24841,54245:28189,54246:28180,54247:38533,54248:20104,54249:23089,54250:38632,54251:19982,54252:23679,54253:31161,54254:23431,54255:35821,54256:32701,54257:29577,54258:22495,54259:33419,54260:37057,54261:21505,54262:36935,54263:21947,54264:23786,54265:24481,54266:24840,54267:27442,54268:29425,54269:32946,54270:35465,54336:35358,54337:35359,54338:35360,54339:35361,54340:35362,54341:35363,54342:35364,54343:35365,54344:35366,54345:35367,54346:35368,54347:35369,54348:35370,54349:35371,54350:35372,54351:35373,54352:35374,54353:35375,54354:35376,54355:35377,54356:35378,54357:35379,54358:35380,54359:35381,54360:35382,54361:35383,54362:35384,54363:35385,54364:35386,54365:35387,54366:35388,54367:35389,54368:35391,54369:35392,54370:35393,54371:35394,54372:35395,54373:35396,54374:35397,54375:35398,54376:35399,54377:35401,54378:35402,54379:35403,54380:35404,54381:35405,54382:35406,54383:35407,54384:35408,54385:35409,54386:35410,54387:35411,54388:35412,54389:35413,54390:35414,54391:35415,54392:35416,54393:35417,54394:35418,54395:35419,54396:35420,54397:35421,54398:35422,54400:35423,54401:35424,54402:35425,54403:35426,54404:35427,54405:35428,54406:35429,54407:35430,54408:35431,54409:35432,54410:35433,54411:35434,54412:35435,54413:35436,54414:35437,54415:35438,54416:35439,54417:35440,54418:35441,54419:35442,54420:35443,54421:35444,54422:35445,54423:35446,54424:35447,54425:35448,54426:35450,54427:35451,54428:35452,54429:35453,54430:35454,54431:35455,54432:35456,54433:28020,54434:23507,54435:35029,54436:39044,54437:35947,54438:39533,54439:40499,54440:28170,54441:20900,54442:20803,54443:22435,54444:34945,54445:21407,54446:25588,54447:36757,54448:22253,54449:21592,54450:22278,54451:29503,54452:28304,54453:32536,54454:36828,54455:33489,54456:24895,54457:24616,54458:38498,54459:26352,54460:32422,54461:36234,54462:36291,54463:38053,54464:23731,54465:31908,54466:26376,54467:24742,54468:38405,54469:32792,54470:20113,54471:37095,54472:21248,54473:38504,54474:20801,54475:36816,54476:34164,54477:37213,54478:26197,54479:38901,54480:23381,54481:21277,54482:30776,54483:26434,54484:26685,54485:21705,54486:28798,54487:23472,54488:36733,54489:20877,54490:22312,54491:21681,54492:25874,54493:26242,54494:36190,54495:36163,54496:33039,54497:33900,54498:36973,54499:31967,54500:20991,54501:34299,54502:26531,54503:26089,54504:28577,54505:34468,54506:36481,54507:22122,54508:36896,54509:30338,54510:28790,54511:29157,54512:36131,54513:25321,54514:21017,54515:27901,54516:36156,54517:24590,54518:22686,54519:24974,54520:26366,54521:36192,54522:25166,54523:21939,54524:28195,54525:26413,54526:36711,54592:35457,54593:35458,54594:35459,54595:35460,54596:35461,54597:35462,54598:35463,54599:35464,54600:35467,54601:35468,54602:35469,54603:35470,54604:35471,54605:35472,54606:35473,54607:35474,54608:35476,54609:35477,54610:35478,54611:35479,54612:35480,54613:35481,54614:35482,54615:35483,54616:35484,54617:35485,54618:35486,54619:35487,54620:35488,54621:35489,54622:35490,54623:35491,54624:35492,54625:35493,54626:35494,54627:35495,54628:35496,54629:35497,54630:35498,54631:35499,54632:35500,54633:35501,54634:35502,54635:35503,54636:35504,54637:35505,54638:35506,54639:35507,54640:35508,54641:35509,54642:35510,54643:35511,54644:35512,54645:35513,54646:35514,54647:35515,54648:35516,54649:35517,54650:35518,54651:35519,54652:35520,54653:35521,54654:35522,54656:35523,54657:35524,54658:35525,54659:35526,54660:35527,54661:35528,54662:35529,54663:35530,54664:35531,54665:35532,54666:35533,54667:35534,54668:35535,54669:35536,54670:35537,54671:35538,54672:35539,54673:35540,54674:35541,54675:35542,54676:35543,54677:35544,54678:35545,54679:35546,54680:35547,54681:35548,54682:35549,54683:35550,54684:35551,54685:35552,54686:35553,54687:35554,54688:35555,54689:38113,54690:38392,54691:30504,54692:26629,54693:27048,54694:21643,54695:20045,54696:28856,54697:35784,54698:25688,54699:25995,54700:23429,54701:31364,54702:20538,54703:23528,54704:30651,54705:27617,54706:35449,54707:31896,54708:27838,54709:30415,54710:26025,54711:36759,54712:23853,54713:23637,54714:34360,54715:26632,54716:21344,54717:25112,54718:31449,54719:28251,54720:32509,54721:27167,54722:31456,54723:24432,54724:28467,54725:24352,54726:25484,54727:28072,54728:26454,54729:19976,54730:24080,54731:36134,54732:20183,54733:32960,54734:30260,54735:38556,54736:25307,54737:26157,54738:25214,54739:27836,54740:36213,54741:29031,54742:32617,54743:20806,54744:32903,54745:21484,54746:36974,54747:25240,54748:21746,54749:34544,54750:36761,54751:32773,54752:38167,54753:34071,54754:36825,54755:27993,54756:29645,54757:26015,54758:30495,54759:29956,54760:30759,54761:33275,54762:36126,54763:38024,54764:20390,54765:26517,54766:30137,54767:35786,54768:38663,54769:25391,54770:38215,54771:38453,54772:33976,54773:25379,54774:30529,54775:24449,54776:29424,54777:20105,54778:24596,54779:25972,54780:25327,54781:27491,54782:25919,54848:35556,54849:35557,54850:35558,54851:35559,54852:35560,54853:35561,54854:35562,54855:35563,54856:35564,54857:35565,54858:35566,54859:35567,54860:35568,54861:35569,54862:35570,54863:35571,54864:35572,54865:35573,54866:35574,54867:35575,54868:35576,54869:35577,54870:35578,54871:35579,54872:35580,54873:35581,54874:35582,54875:35583,54876:35584,54877:35585,54878:35586,54879:35587,54880:35588,54881:35589,54882:35590,54883:35592,54884:35593,54885:35594,54886:35595,54887:35596,54888:35597,54889:35598,54890:35599,54891:35600,54892:35601,54893:35602,54894:35603,54895:35604,54896:35605,54897:35606,54898:35607,54899:35608,54900:35609,54901:35610,54902:35611,54903:35612,54904:35613,54905:35614,54906:35615,54907:35616,54908:35617,54909:35618,54910:35619,54912:35620,54913:35621,54914:35623,54915:35624,54916:35625,54917:35626,54918:35627,54919:35628,54920:35629,54921:35630,54922:35631,54923:35632,54924:35633,54925:35634,54926:35635,54927:35636,54928:35637,54929:35638,54930:35639,54931:35640,54932:35641,54933:35642,54934:35643,54935:35644,54936:35645,54937:35646,54938:35647,54939:35648,54940:35649,54941:35650,54942:35651,54943:35652,54944:35653,54945:24103,54946:30151,54947:37073,54948:35777,54949:33437,54950:26525,54951:25903,54952:21553,54953:34584,54954:30693,54955:32930,54956:33026,54957:27713,54958:20043,54959:32455,54960:32844,54961:30452,54962:26893,54963:27542,54964:25191,54965:20540,54966:20356,54967:22336,54968:25351,54969:27490,54970:36286,54971:21482,54972:26088,54973:32440,54974:24535,54975:25370,54976:25527,54977:33267,54978:33268,54979:32622,54980:24092,54981:23769,54982:21046,54983:26234,54984:31209,54985:31258,54986:36136,54987:28825,54988:30164,54989:28382,54990:27835,54991:31378,54992:20013,54993:30405,54994:24544,54995:38047,54996:34935,54997:32456,54998:31181,54999:32959,55000:37325,55001:20210,55002:20247,55003:33311,55004:21608,55005:24030,55006:27954,55007:35788,55008:31909,55009:36724,55010:32920,55011:24090,55012:21650,55013:30385,55014:23449,55015:26172,55016:39588,55017:29664,55018:26666,55019:34523,55020:26417,55021:29482,55022:35832,55023:35803,55024:36880,55025:31481,55026:28891,55027:29038,55028:25284,55029:30633,55030:22065,55031:20027,55032:33879,55033:26609,55034:21161,55035:34496,55036:36142,55037:38136,55038:31569,55104:35654,55105:35655,55106:35656,55107:35657,55108:35658,55109:35659,55110:35660,55111:35661,55112:35662,55113:35663,55114:35664,55115:35665,55116:35666,55117:35667,55118:35668,55119:35669,55120:35670,55121:35671,55122:35672,55123:35673,55124:35674,55125:35675,55126:35676,55127:35677,55128:35678,55129:35679,55130:35680,55131:35681,55132:35682,55133:35683,55134:35684,55135:35685,55136:35687,55137:35688,55138:35689,55139:35690,55140:35691,55141:35693,55142:35694,55143:35695,55144:35696,55145:35697,55146:35698,55147:35699,55148:35700,55149:35701,55150:35702,55151:35703,55152:35704,55153:35705,55154:35706,55155:35707,55156:35708,55157:35709,55158:35710,55159:35711,55160:35712,55161:35713,55162:35714,55163:35715,55164:35716,55165:35717,55166:35718,55168:35719,55169:35720,55170:35721,55171:35722,55172:35723,55173:35724,55174:35725,55175:35726,55176:35727,55177:35728,55178:35729,55179:35730,55180:35731,55181:35732,55182:35733,55183:35734,55184:35735,55185:35736,55186:35737,55187:35738,55188:35739,55189:35740,55190:35741,55191:35742,55192:35743,55193:35756,55194:35761,55195:35771,55196:35783,55197:35792,55198:35818,55199:35849,55200:35870,55201:20303,55202:27880,55203:31069,55204:39547,55205:25235,55206:29226,55207:25341,55208:19987,55209:30742,55210:36716,55211:25776,55212:36186,55213:31686,55214:26729,55215:24196,55216:35013,55217:22918,55218:25758,55219:22766,55220:29366,55221:26894,55222:38181,55223:36861,55224:36184,55225:22368,55226:32512,55227:35846,55228:20934,55229:25417,55230:25305,55231:21331,55232:26700,55233:29730,55234:33537,55235:37196,55236:21828,55237:30528,55238:28796,55239:27978,55240:20857,55241:21672,55242:36164,55243:23039,55244:28363,55245:28100,55246:23388,55247:32043,55248:20180,55249:31869,55250:28371,55251:23376,55252:33258,55253:28173,55254:23383,55255:39683,55256:26837,55257:36394,55258:23447,55259:32508,55260:24635,55261:32437,55262:37049,55263:36208,55264:22863,55265:25549,55266:31199,55267:36275,55268:21330,55269:26063,55270:31062,55271:35781,55272:38459,55273:32452,55274:38075,55275:32386,55276:22068,55277:37257,55278:26368,55279:32618,55280:23562,55281:36981,55282:26152,55283:24038,55284:20304,55285:26590,55286:20570,55287:20316,55288:22352,55289:24231,55290:59408,55291:59409,55292:59410,55293:59411,55294:59412,55360:35896,55361:35897,55362:35898,55363:35899,55364:35900,55365:35901,55366:35902,55367:35903,55368:35904,55369:35906,55370:35907,55371:35908,55372:35909,55373:35912,55374:35914,55375:35915,55376:35917,55377:35918,55378:35919,55379:35920,55380:35921,55381:35922,55382:35923,55383:35924,55384:35926,55385:35927,55386:35928,55387:35929,55388:35931,55389:35932,55390:35933,55391:35934,55392:35935,55393:35936,55394:35939,55395:35940,55396:35941,55397:35942,55398:35943,55399:35944,55400:35945,55401:35948,55402:35949,55403:35950,55404:35951,55405:35952,55406:35953,55407:35954,55408:35956,55409:35957,55410:35958,55411:35959,55412:35963,55413:35964,55414:35965,55415:35966,55416:35967,55417:35968,55418:35969,55419:35971,55420:35972,55421:35974,55422:35975,55424:35976,55425:35979,55426:35981,55427:35982,55428:35983,55429:35984,55430:35985,55431:35986,55432:35987,55433:35989,55434:35990,55435:35991,55436:35993,55437:35994,55438:35995,55439:35996,55440:35997,55441:35998,55442:35999,55443:36000,55444:36001,55445:36002,55446:36003,55447:36004,55448:36005,55449:36006,55450:36007,55451:36008,55452:36009,55453:36010,55454:36011,55455:36012,55456:36013,55457:20109,55458:19980,55459:20800,55460:19984,55461:24319,55462:21317,55463:19989,55464:20120,55465:19998,55466:39730,55467:23404,55468:22121,55469:20008,55470:31162,55471:20031,55472:21269,55473:20039,55474:22829,55475:29243,55476:21358,55477:27664,55478:22239,55479:32996,55480:39319,55481:27603,55482:30590,55483:40727,55484:20022,55485:20127,55486:40720,55487:20060,55488:20073,55489:20115,55490:33416,55491:23387,55492:21868,55493:22031,55494:20164,55495:21389,55496:21405,55497:21411,55498:21413,55499:21422,55500:38757,55501:36189,55502:21274,55503:21493,55504:21286,55505:21294,55506:21310,55507:36188,55508:21350,55509:21347,55510:20994,55511:21000,55512:21006,55513:21037,55514:21043,55515:21055,55516:21056,55517:21068,55518:21086,55519:21089,55520:21084,55521:33967,55522:21117,55523:21122,55524:21121,55525:21136,55526:21139,55527:20866,55528:32596,55529:20155,55530:20163,55531:20169,55532:20162,55533:20200,55534:20193,55535:20203,55536:20190,55537:20251,55538:20211,55539:20258,55540:20324,55541:20213,55542:20261,55543:20263,55544:20233,55545:20267,55546:20318,55547:20327,55548:25912,55549:20314,55550:20317,55616:36014,55617:36015,55618:36016,55619:36017,55620:36018,55621:36019,55622:36020,55623:36021,55624:36022,55625:36023,55626:36024,55627:36025,55628:36026,55629:36027,55630:36028,55631:36029,55632:36030,55633:36031,55634:36032,55635:36033,55636:36034,55637:36035,55638:36036,55639:36037,55640:36038,55641:36039,55642:36040,55643:36041,55644:36042,55645:36043,55646:36044,55647:36045,55648:36046,55649:36047,55650:36048,55651:36049,55652:36050,55653:36051,55654:36052,55655:36053,55656:36054,55657:36055,55658:36056,55659:36057,55660:36058,55661:36059,55662:36060,55663:36061,55664:36062,55665:36063,55666:36064,55667:36065,55668:36066,55669:36067,55670:36068,55671:36069,55672:36070,55673:36071,55674:36072,55675:36073,55676:36074,55677:36075,55678:36076,55680:36077,55681:36078,55682:36079,55683:36080,55684:36081,55685:36082,55686:36083,55687:36084,55688:36085,55689:36086,55690:36087,55691:36088,55692:36089,55693:36090,55694:36091,55695:36092,55696:36093,55697:36094,55698:36095,55699:36096,55700:36097,55701:36098,55702:36099,55703:36100,55704:36101,55705:36102,55706:36103,55707:36104,55708:36105,55709:36106,55710:36107,55711:36108,55712:36109,55713:20319,55714:20311,55715:20274,55716:20285,55717:20342,55718:20340,55719:20369,55720:20361,55721:20355,55722:20367,55723:20350,55724:20347,55725:20394,55726:20348,55727:20396,55728:20372,55729:20454,55730:20456,55731:20458,55732:20421,55733:20442,55734:20451,55735:20444,55736:20433,55737:20447,55738:20472,55739:20521,55740:20556,55741:20467,55742:20524,55743:20495,55744:20526,55745:20525,55746:20478,55747:20508,55748:20492,55749:20517,55750:20520,55751:20606,55752:20547,55753:20565,55754:20552,55755:20558,55756:20588,55757:20603,55758:20645,55759:20647,55760:20649,55761:20666,55762:20694,55763:20742,55764:20717,55765:20716,55766:20710,55767:20718,55768:20743,55769:20747,55770:20189,55771:27709,55772:20312,55773:20325,55774:20430,55775:40864,55776:27718,55777:31860,55778:20846,55779:24061,55780:40649,55781:39320,55782:20865,55783:22804,55784:21241,55785:21261,55786:35335,55787:21264,55788:20971,55789:22809,55790:20821,55791:20128,55792:20822,55793:20147,55794:34926,55795:34980,55796:20149,55797:33044,55798:35026,55799:31104,55800:23348,55801:34819,55802:32696,55803:20907,55804:20913,55805:20925,55806:20924,55872:36110,55873:36111,55874:36112,55875:36113,55876:36114,55877:36115,55878:36116,55879:36117,55880:36118,55881:36119,55882:36120,55883:36121,55884:36122,55885:36123,55886:36124,55887:36128,55888:36177,55889:36178,55890:36183,55891:36191,55892:36197,55893:36200,55894:36201,55895:36202,55896:36204,55897:36206,55898:36207,55899:36209,55900:36210,55901:36216,55902:36217,55903:36218,55904:36219,55905:36220,55906:36221,55907:36222,55908:36223,55909:36224,55910:36226,55911:36227,55912:36230,55913:36231,55914:36232,55915:36233,55916:36236,55917:36237,55918:36238,55919:36239,55920:36240,55921:36242,55922:36243,55923:36245,55924:36246,55925:36247,55926:36248,55927:36249,55928:36250,55929:36251,55930:36252,55931:36253,55932:36254,55933:36256,55934:36257,55936:36258,55937:36260,55938:36261,55939:36262,55940:36263,55941:36264,55942:36265,55943:36266,55944:36267,55945:36268,55946:36269,55947:36270,55948:36271,55949:36272,55950:36274,55951:36278,55952:36279,55953:36281,55954:36283,55955:36285,55956:36288,55957:36289,55958:36290,55959:36293,55960:36295,55961:36296,55962:36297,55963:36298,55964:36301,55965:36304,55966:36306,55967:36307,55968:36308,55969:20935,55970:20886,55971:20898,55972:20901,55973:35744,55974:35750,55975:35751,55976:35754,55977:35764,55978:35765,55979:35767,55980:35778,55981:35779,55982:35787,55983:35791,55984:35790,55985:35794,55986:35795,55987:35796,55988:35798,55989:35800,55990:35801,55991:35804,55992:35807,55993:35808,55994:35812,55995:35816,55996:35817,55997:35822,55998:35824,55999:35827,56000:35830,56001:35833,56002:35836,56003:35839,56004:35840,56005:35842,56006:35844,56007:35847,56008:35852,56009:35855,56010:35857,56011:35858,56012:35860,56013:35861,56014:35862,56015:35865,56016:35867,56017:35864,56018:35869,56019:35871,56020:35872,56021:35873,56022:35877,56023:35879,56024:35882,56025:35883,56026:35886,56027:35887,56028:35890,56029:35891,56030:35893,56031:35894,56032:21353,56033:21370,56034:38429,56035:38434,56036:38433,56037:38449,56038:38442,56039:38461,56040:38460,56041:38466,56042:38473,56043:38484,56044:38495,56045:38503,56046:38508,56047:38514,56048:38516,56049:38536,56050:38541,56051:38551,56052:38576,56053:37015,56054:37019,56055:37021,56056:37017,56057:37036,56058:37025,56059:37044,56060:37043,56061:37046,56062:37050,56128:36309,56129:36312,56130:36313,56131:36316,56132:36320,56133:36321,56134:36322,56135:36325,56136:36326,56137:36327,56138:36329,56139:36333,56140:36334,56141:36336,56142:36337,56143:36338,56144:36340,56145:36342,56146:36348,56147:36350,56148:36351,56149:36352,56150:36353,56151:36354,56152:36355,56153:36356,56154:36358,56155:36359,56156:36360,56157:36363,56158:36365,56159:36366,56160:36368,56161:36369,56162:36370,56163:36371,56164:36373,56165:36374,56166:36375,56167:36376,56168:36377,56169:36378,56170:36379,56171:36380,56172:36384,56173:36385,56174:36388,56175:36389,56176:36390,56177:36391,56178:36392,56179:36395,56180:36397,56181:36400,56182:36402,56183:36403,56184:36404,56185:36406,56186:36407,56187:36408,56188:36411,56189:36412,56190:36414,56192:36415,56193:36419,56194:36421,56195:36422,56196:36428,56197:36429,56198:36430,56199:36431,56200:36432,56201:36435,56202:36436,56203:36437,56204:36438,56205:36439,56206:36440,56207:36442,56208:36443,56209:36444,56210:36445,56211:36446,56212:36447,56213:36448,56214:36449,56215:36450,56216:36451,56217:36452,56218:36453,56219:36455,56220:36456,56221:36458,56222:36459,56223:36462,56224:36465,56225:37048,56226:37040,56227:37071,56228:37061,56229:37054,56230:37072,56231:37060,56232:37063,56233:37075,56234:37094,56235:37090,56236:37084,56237:37079,56238:37083,56239:37099,56240:37103,56241:37118,56242:37124,56243:37154,56244:37150,56245:37155,56246:37169,56247:37167,56248:37177,56249:37187,56250:37190,56251:21005,56252:22850,56253:21154,56254:21164,56255:21165,56256:21182,56257:21759,56258:21200,56259:21206,56260:21232,56261:21471,56262:29166,56263:30669,56264:24308,56265:20981,56266:20988,56267:39727,56268:21430,56269:24321,56270:30042,56271:24047,56272:22348,56273:22441,56274:22433,56275:22654,56276:22716,56277:22725,56278:22737,56279:22313,56280:22316,56281:22314,56282:22323,56283:22329,56284:22318,56285:22319,56286:22364,56287:22331,56288:22338,56289:22377,56290:22405,56291:22379,56292:22406,56293:22396,56294:22395,56295:22376,56296:22381,56297:22390,56298:22387,56299:22445,56300:22436,56301:22412,56302:22450,56303:22479,56304:22439,56305:22452,56306:22419,56307:22432,56308:22485,56309:22488,56310:22490,56311:22489,56312:22482,56313:22456,56314:22516,56315:22511,56316:22520,56317:22500,56318:22493,56384:36467,56385:36469,56386:36471,56387:36472,56388:36473,56389:36474,56390:36475,56391:36477,56392:36478,56393:36480,56394:36482,56395:36483,56396:36484,56397:36486,56398:36488,56399:36489,56400:36490,56401:36491,56402:36492,56403:36493,56404:36494,56405:36497,56406:36498,56407:36499,56408:36501,56409:36502,56410:36503,56411:36504,56412:36505,56413:36506,56414:36507,56415:36509,56416:36511,56417:36512,56418:36513,56419:36514,56420:36515,56421:36516,56422:36517,56423:36518,56424:36519,56425:36520,56426:36521,56427:36522,56428:36525,56429:36526,56430:36528,56431:36529,56432:36531,56433:36532,56434:36533,56435:36534,56436:36535,56437:36536,56438:36537,56439:36539,56440:36540,56441:36541,56442:36542,56443:36543,56444:36544,56445:36545,56446:36546,56448:36547,56449:36548,56450:36549,56451:36550,56452:36551,56453:36552,56454:36553,56455:36554,56456:36555,56457:36556,56458:36557,56459:36559,56460:36560,56461:36561,56462:36562,56463:36563,56464:36564,56465:36565,56466:36566,56467:36567,56468:36568,56469:36569,56470:36570,56471:36571,56472:36572,56473:36573,56474:36574,56475:36575,56476:36576,56477:36577,56478:36578,56479:36579,56480:36580,56481:22539,56482:22541,56483:22525,56484:22509,56485:22528,56486:22558,56487:22553,56488:22596,56489:22560,56490:22629,56491:22636,56492:22657,56493:22665,56494:22682,56495:22656,56496:39336,56497:40729,56498:25087,56499:33401,56500:33405,56501:33407,56502:33423,56503:33418,56504:33448,56505:33412,56506:33422,56507:33425,56508:33431,56509:33433,56510:33451,56511:33464,56512:33470,56513:33456,56514:33480,56515:33482,56516:33507,56517:33432,56518:33463,56519:33454,56520:33483,56521:33484,56522:33473,56523:33449,56524:33460,56525:33441,56526:33450,56527:33439,56528:33476,56529:33486,56530:33444,56531:33505,56532:33545,56533:33527,56534:33508,56535:33551,56536:33543,56537:33500,56538:33524,56539:33490,56540:33496,56541:33548,56542:33531,56543:33491,56544:33553,56545:33562,56546:33542,56547:33556,56548:33557,56549:33504,56550:33493,56551:33564,56552:33617,56553:33627,56554:33628,56555:33544,56556:33682,56557:33596,56558:33588,56559:33585,56560:33691,56561:33630,56562:33583,56563:33615,56564:33607,56565:33603,56566:33631,56567:33600,56568:33559,56569:33632,56570:33581,56571:33594,56572:33587,56573:33638,56574:33637,56640:36581,56641:36582,56642:36583,56643:36584,56644:36585,56645:36586,56646:36587,56647:36588,56648:36589,56649:36590,56650:36591,56651:36592,56652:36593,56653:36594,56654:36595,56655:36596,56656:36597,56657:36598,56658:36599,56659:36600,56660:36601,56661:36602,56662:36603,56663:36604,56664:36605,56665:36606,56666:36607,56667:36608,56668:36609,56669:36610,56670:36611,56671:36612,56672:36613,56673:36614,56674:36615,56675:36616,56676:36617,56677:36618,56678:36619,56679:36620,56680:36621,56681:36622,56682:36623,56683:36624,56684:36625,56685:36626,56686:36627,56687:36628,56688:36629,56689:36630,56690:36631,56691:36632,56692:36633,56693:36634,56694:36635,56695:36636,56696:36637,56697:36638,56698:36639,56699:36640,56700:36641,56701:36642,56702:36643,56704:36644,56705:36645,56706:36646,56707:36647,56708:36648,56709:36649,56710:36650,56711:36651,56712:36652,56713:36653,56714:36654,56715:36655,56716:36656,56717:36657,56718:36658,56719:36659,56720:36660,56721:36661,56722:36662,56723:36663,56724:36664,56725:36665,56726:36666,56727:36667,56728:36668,56729:36669,56730:36670,56731:36671,56732:36672,56733:36673,56734:36674,56735:36675,56736:36676,56737:33640,56738:33563,56739:33641,56740:33644,56741:33642,56742:33645,56743:33646,56744:33712,56745:33656,56746:33715,56747:33716,56748:33696,56749:33706,56750:33683,56751:33692,56752:33669,56753:33660,56754:33718,56755:33705,56756:33661,56757:33720,56758:33659,56759:33688,56760:33694,56761:33704,56762:33722,56763:33724,56764:33729,56765:33793,56766:33765,56767:33752,56768:22535,56769:33816,56770:33803,56771:33757,56772:33789,56773:33750,56774:33820,56775:33848,56776:33809,56777:33798,56778:33748,56779:33759,56780:33807,56781:33795,56782:33784,56783:33785,56784:33770,56785:33733,56786:33728,56787:33830,56788:33776,56789:33761,56790:33884,56791:33873,56792:33882,56793:33881,56794:33907,56795:33927,56796:33928,56797:33914,56798:33929,56799:33912,56800:33852,56801:33862,56802:33897,56803:33910,56804:33932,56805:33934,56806:33841,56807:33901,56808:33985,56809:33997,56810:34000,56811:34022,56812:33981,56813:34003,56814:33994,56815:33983,56816:33978,56817:34016,56818:33953,56819:33977,56820:33972,56821:33943,56822:34021,56823:34019,56824:34060,56825:29965,56826:34104,56827:34032,56828:34105,56829:34079,56830:34106,56896:36677,56897:36678,56898:36679,56899:36680,56900:36681,56901:36682,56902:36683,56903:36684,56904:36685,56905:36686,56906:36687,56907:36688,56908:36689,56909:36690,56910:36691,56911:36692,56912:36693,56913:36694,56914:36695,56915:36696,56916:36697,56917:36698,56918:36699,56919:36700,56920:36701,56921:36702,56922:36703,56923:36704,56924:36705,56925:36706,56926:36707,56927:36708,56928:36709,56929:36714,56930:36736,56931:36748,56932:36754,56933:36765,56934:36768,56935:36769,56936:36770,56937:36772,56938:36773,56939:36774,56940:36775,56941:36778,56942:36780,56943:36781,56944:36782,56945:36783,56946:36786,56947:36787,56948:36788,56949:36789,56950:36791,56951:36792,56952:36794,56953:36795,56954:36796,56955:36799,56956:36800,56957:36803,56958:36806,56960:36809,56961:36810,56962:36811,56963:36812,56964:36813,56965:36815,56966:36818,56967:36822,56968:36823,56969:36826,56970:36832,56971:36833,56972:36835,56973:36839,56974:36844,56975:36847,56976:36849,56977:36850,56978:36852,56979:36853,56980:36854,56981:36858,56982:36859,56983:36860,56984:36862,56985:36863,56986:36871,56987:36872,56988:36876,56989:36878,56990:36883,56991:36885,56992:36888,56993:34134,56994:34107,56995:34047,56996:34044,56997:34137,56998:34120,56999:34152,57000:34148,57001:34142,57002:34170,57003:30626,57004:34115,57005:34162,57006:34171,57007:34212,57008:34216,57009:34183,57010:34191,57011:34169,57012:34222,57013:34204,57014:34181,57015:34233,57016:34231,57017:34224,57018:34259,57019:34241,57020:34268,57021:34303,57022:34343,57023:34309,57024:34345,57025:34326,57026:34364,57027:24318,57028:24328,57029:22844,57030:22849,57031:32823,57032:22869,57033:22874,57034:22872,57035:21263,57036:23586,57037:23589,57038:23596,57039:23604,57040:25164,57041:25194,57042:25247,57043:25275,57044:25290,57045:25306,57046:25303,57047:25326,57048:25378,57049:25334,57050:25401,57051:25419,57052:25411,57053:25517,57054:25590,57055:25457,57056:25466,57057:25486,57058:25524,57059:25453,57060:25516,57061:25482,57062:25449,57063:25518,57064:25532,57065:25586,57066:25592,57067:25568,57068:25599,57069:25540,57070:25566,57071:25550,57072:25682,57073:25542,57074:25534,57075:25669,57076:25665,57077:25611,57078:25627,57079:25632,57080:25612,57081:25638,57082:25633,57083:25694,57084:25732,57085:25709,57086:25750,57152:36889,57153:36892,57154:36899,57155:36900,57156:36901,57157:36903,57158:36904,57159:36905,57160:36906,57161:36907,57162:36908,57163:36912,57164:36913,57165:36914,57166:36915,57167:36916,57168:36919,57169:36921,57170:36922,57171:36925,57172:36927,57173:36928,57174:36931,57175:36933,57176:36934,57177:36936,57178:36937,57179:36938,57180:36939,57181:36940,57182:36942,57183:36948,57184:36949,57185:36950,57186:36953,57187:36954,57188:36956,57189:36957,57190:36958,57191:36959,57192:36960,57193:36961,57194:36964,57195:36966,57196:36967,57197:36969,57198:36970,57199:36971,57200:36972,57201:36975,57202:36976,57203:36977,57204:36978,57205:36979,57206:36982,57207:36983,57208:36984,57209:36985,57210:36986,57211:36987,57212:36988,57213:36990,57214:36993,57216:36996,57217:36997,57218:36998,57219:36999,57220:37001,57221:37002,57222:37004,57223:37005,57224:37006,57225:37007,57226:37008,57227:37010,57228:37012,57229:37014,57230:37016,57231:37018,57232:37020,57233:37022,57234:37023,57235:37024,57236:37028,57237:37029,57238:37031,57239:37032,57240:37033,57241:37035,57242:37037,57243:37042,57244:37047,57245:37052,57246:37053,57247:37055,57248:37056,57249:25722,57250:25783,57251:25784,57252:25753,57253:25786,57254:25792,57255:25808,57256:25815,57257:25828,57258:25826,57259:25865,57260:25893,57261:25902,57262:24331,57263:24530,57264:29977,57265:24337,57266:21343,57267:21489,57268:21501,57269:21481,57270:21480,57271:21499,57272:21522,57273:21526,57274:21510,57275:21579,57276:21586,57277:21587,57278:21588,57279:21590,57280:21571,57281:21537,57282:21591,57283:21593,57284:21539,57285:21554,57286:21634,57287:21652,57288:21623,57289:21617,57290:21604,57291:21658,57292:21659,57293:21636,57294:21622,57295:21606,57296:21661,57297:21712,57298:21677,57299:21698,57300:21684,57301:21714,57302:21671,57303:21670,57304:21715,57305:21716,57306:21618,57307:21667,57308:21717,57309:21691,57310:21695,57311:21708,57312:21721,57313:21722,57314:21724,57315:21673,57316:21674,57317:21668,57318:21725,57319:21711,57320:21726,57321:21787,57322:21735,57323:21792,57324:21757,57325:21780,57326:21747,57327:21794,57328:21795,57329:21775,57330:21777,57331:21799,57332:21802,57333:21863,57334:21903,57335:21941,57336:21833,57337:21869,57338:21825,57339:21845,57340:21823,57341:21840,57342:21820,57408:37058,57409:37059,57410:37062,57411:37064,57412:37065,57413:37067,57414:37068,57415:37069,57416:37074,57417:37076,57418:37077,57419:37078,57420:37080,57421:37081,57422:37082,57423:37086,57424:37087,57425:37088,57426:37091,57427:37092,57428:37093,57429:37097,57430:37098,57431:37100,57432:37102,57433:37104,57434:37105,57435:37106,57436:37107,57437:37109,57438:37110,57439:37111,57440:37113,57441:37114,57442:37115,57443:37116,57444:37119,57445:37120,57446:37121,57447:37123,57448:37125,57449:37126,57450:37127,57451:37128,57452:37129,57453:37130,57454:37131,57455:37132,57456:37133,57457:37134,57458:37135,57459:37136,57460:37137,57461:37138,57462:37139,57463:37140,57464:37141,57465:37142,57466:37143,57467:37144,57468:37146,57469:37147,57470:37148,57472:37149,57473:37151,57474:37152,57475:37153,57476:37156,57477:37157,57478:37158,57479:37159,57480:37160,57481:37161,57482:37162,57483:37163,57484:37164,57485:37165,57486:37166,57487:37168,57488:37170,57489:37171,57490:37172,57491:37173,57492:37174,57493:37175,57494:37176,57495:37178,57496:37179,57497:37180,57498:37181,57499:37182,57500:37183,57501:37184,57502:37185,57503:37186,57504:37188,57505:21815,57506:21846,57507:21877,57508:21878,57509:21879,57510:21811,57511:21808,57512:21852,57513:21899,57514:21970,57515:21891,57516:21937,57517:21945,57518:21896,57519:21889,57520:21919,57521:21886,57522:21974,57523:21905,57524:21883,57525:21983,57526:21949,57527:21950,57528:21908,57529:21913,57530:21994,57531:22007,57532:21961,57533:22047,57534:21969,57535:21995,57536:21996,57537:21972,57538:21990,57539:21981,57540:21956,57541:21999,57542:21989,57543:22002,57544:22003,57545:21964,57546:21965,57547:21992,57548:22005,57549:21988,57550:36756,57551:22046,57552:22024,57553:22028,57554:22017,57555:22052,57556:22051,57557:22014,57558:22016,57559:22055,57560:22061,57561:22104,57562:22073,57563:22103,57564:22060,57565:22093,57566:22114,57567:22105,57568:22108,57569:22092,57570:22100,57571:22150,57572:22116,57573:22129,57574:22123,57575:22139,57576:22140,57577:22149,57578:22163,57579:22191,57580:22228,57581:22231,57582:22237,57583:22241,57584:22261,57585:22251,57586:22265,57587:22271,57588:22276,57589:22282,57590:22281,57591:22300,57592:24079,57593:24089,57594:24084,57595:24081,57596:24113,57597:24123,57598:24124,57664:37189,57665:37191,57666:37192,57667:37201,57668:37203,57669:37204,57670:37205,57671:37206,57672:37208,57673:37209,57674:37211,57675:37212,57676:37215,57677:37216,57678:37222,57679:37223,57680:37224,57681:37227,57682:37229,57683:37235,57684:37242,57685:37243,57686:37244,57687:37248,57688:37249,57689:37250,57690:37251,57691:37252,57692:37254,57693:37256,57694:37258,57695:37262,57696:37263,57697:37267,57698:37268,57699:37269,57700:37270,57701:37271,57702:37272,57703:37273,57704:37276,57705:37277,57706:37278,57707:37279,57708:37280,57709:37281,57710:37284,57711:37285,57712:37286,57713:37287,57714:37288,57715:37289,57716:37291,57717:37292,57718:37296,57719:37297,57720:37298,57721:37299,57722:37302,57723:37303,57724:37304,57725:37305,57726:37307,57728:37308,57729:37309,57730:37310,57731:37311,57732:37312,57733:37313,57734:37314,57735:37315,57736:37316,57737:37317,57738:37318,57739:37320,57740:37323,57741:37328,57742:37330,57743:37331,57744:37332,57745:37333,57746:37334,57747:37335,57748:37336,57749:37337,57750:37338,57751:37339,57752:37341,57753:37342,57754:37343,57755:37344,57756:37345,57757:37346,57758:37347,57759:37348,57760:37349,57761:24119,57762:24132,57763:24148,57764:24155,57765:24158,57766:24161,57767:23692,57768:23674,57769:23693,57770:23696,57771:23702,57772:23688,57773:23704,57774:23705,57775:23697,57776:23706,57777:23708,57778:23733,57779:23714,57780:23741,57781:23724,57782:23723,57783:23729,57784:23715,57785:23745,57786:23735,57787:23748,57788:23762,57789:23780,57790:23755,57791:23781,57792:23810,57793:23811,57794:23847,57795:23846,57796:23854,57797:23844,57798:23838,57799:23814,57800:23835,57801:23896,57802:23870,57803:23860,57804:23869,57805:23916,57806:23899,57807:23919,57808:23901,57809:23915,57810:23883,57811:23882,57812:23913,57813:23924,57814:23938,57815:23961,57816:23965,57817:35955,57818:23991,57819:24005,57820:24435,57821:24439,57822:24450,57823:24455,57824:24457,57825:24460,57826:24469,57827:24473,57828:24476,57829:24488,57830:24493,57831:24501,57832:24508,57833:34914,57834:24417,57835:29357,57836:29360,57837:29364,57838:29367,57839:29368,57840:29379,57841:29377,57842:29390,57843:29389,57844:29394,57845:29416,57846:29423,57847:29417,57848:29426,57849:29428,57850:29431,57851:29441,57852:29427,57853:29443,57854:29434,57920:37350,57921:37351,57922:37352,57923:37353,57924:37354,57925:37355,57926:37356,57927:37357,57928:37358,57929:37359,57930:37360,57931:37361,57932:37362,57933:37363,57934:37364,57935:37365,57936:37366,57937:37367,57938:37368,57939:37369,57940:37370,57941:37371,57942:37372,57943:37373,57944:37374,57945:37375,57946:37376,57947:37377,57948:37378,57949:37379,57950:37380,57951:37381,57952:37382,57953:37383,57954:37384,57955:37385,57956:37386,57957:37387,57958:37388,57959:37389,57960:37390,57961:37391,57962:37392,57963:37393,57964:37394,57965:37395,57966:37396,57967:37397,57968:37398,57969:37399,57970:37400,57971:37401,57972:37402,57973:37403,57974:37404,57975:37405,57976:37406,57977:37407,57978:37408,57979:37409,57980:37410,57981:37411,57982:37412,57984:37413,57985:37414,57986:37415,57987:37416,57988:37417,57989:37418,57990:37419,57991:37420,57992:37421,57993:37422,57994:37423,57995:37424,57996:37425,57997:37426,57998:37427,57999:37428,58000:37429,58001:37430,58002:37431,58003:37432,58004:37433,58005:37434,58006:37435,58007:37436,58008:37437,58009:37438,58010:37439,58011:37440,58012:37441,58013:37442,58014:37443,58015:37444,58016:37445,58017:29435,58018:29463,58019:29459,58020:29473,58021:29450,58022:29470,58023:29469,58024:29461,58025:29474,58026:29497,58027:29477,58028:29484,58029:29496,58030:29489,58031:29520,58032:29517,58033:29527,58034:29536,58035:29548,58036:29551,58037:29566,58038:33307,58039:22821,58040:39143,58041:22820,58042:22786,58043:39267,58044:39271,58045:39272,58046:39273,58047:39274,58048:39275,58049:39276,58050:39284,58051:39287,58052:39293,58053:39296,58054:39300,58055:39303,58056:39306,58057:39309,58058:39312,58059:39313,58060:39315,58061:39316,58062:39317,58063:24192,58064:24209,58065:24203,58066:24214,58067:24229,58068:24224,58069:24249,58070:24245,58071:24254,58072:24243,58073:36179,58074:24274,58075:24273,58076:24283,58077:24296,58078:24298,58079:33210,58080:24516,58081:24521,58082:24534,58083:24527,58084:24579,58085:24558,58086:24580,58087:24545,58088:24548,58089:24574,58090:24581,58091:24582,58092:24554,58093:24557,58094:24568,58095:24601,58096:24629,58097:24614,58098:24603,58099:24591,58100:24589,58101:24617,58102:24619,58103:24586,58104:24639,58105:24609,58106:24696,58107:24697,58108:24699,58109:24698,58110:24642,58176:37446,58177:37447,58178:37448,58179:37449,58180:37450,58181:37451,58182:37452,58183:37453,58184:37454,58185:37455,58186:37456,58187:37457,58188:37458,58189:37459,58190:37460,58191:37461,58192:37462,58193:37463,58194:37464,58195:37465,58196:37466,58197:37467,58198:37468,58199:37469,58200:37470,58201:37471,58202:37472,58203:37473,58204:37474,58205:37475,58206:37476,58207:37477,58208:37478,58209:37479,58210:37480,58211:37481,58212:37482,58213:37483,58214:37484,58215:37485,58216:37486,58217:37487,58218:37488,58219:37489,58220:37490,58221:37491,58222:37493,58223:37494,58224:37495,58225:37496,58226:37497,58227:37498,58228:37499,58229:37500,58230:37501,58231:37502,58232:37503,58233:37504,58234:37505,58235:37506,58236:37507,58237:37508,58238:37509,58240:37510,58241:37511,58242:37512,58243:37513,58244:37514,58245:37515,58246:37516,58247:37517,58248:37519,58249:37520,58250:37521,58251:37522,58252:37523,58253:37524,58254:37525,58255:37526,58256:37527,58257:37528,58258:37529,58259:37530,58260:37531,58261:37532,58262:37533,58263:37534,58264:37535,58265:37536,58266:37537,58267:37538,58268:37539,58269:37540,58270:37541,58271:37542,58272:37543,58273:24682,58274:24701,58275:24726,58276:24730,58277:24749,58278:24733,58279:24707,58280:24722,58281:24716,58282:24731,58283:24812,58284:24763,58285:24753,58286:24797,58287:24792,58288:24774,58289:24794,58290:24756,58291:24864,58292:24870,58293:24853,58294:24867,58295:24820,58296:24832,58297:24846,58298:24875,58299:24906,58300:24949,58301:25004,58302:24980,58303:24999,58304:25015,58305:25044,58306:25077,58307:24541,58308:38579,58309:38377,58310:38379,58311:38385,58312:38387,58313:38389,58314:38390,58315:38396,58316:38398,58317:38403,58318:38404,58319:38406,58320:38408,58321:38410,58322:38411,58323:38412,58324:38413,58325:38415,58326:38418,58327:38421,58328:38422,58329:38423,58330:38425,58331:38426,58332:20012,58333:29247,58334:25109,58335:27701,58336:27732,58337:27740,58338:27722,58339:27811,58340:27781,58341:27792,58342:27796,58343:27788,58344:27752,58345:27753,58346:27764,58347:27766,58348:27782,58349:27817,58350:27856,58351:27860,58352:27821,58353:27895,58354:27896,58355:27889,58356:27863,58357:27826,58358:27872,58359:27862,58360:27898,58361:27883,58362:27886,58363:27825,58364:27859,58365:27887,58366:27902,58432:37544,58433:37545,58434:37546,58435:37547,58436:37548,58437:37549,58438:37551,58439:37552,58440:37553,58441:37554,58442:37555,58443:37556,58444:37557,58445:37558,58446:37559,58447:37560,58448:37561,58449:37562,58450:37563,58451:37564,58452:37565,58453:37566,58454:37567,58455:37568,58456:37569,58457:37570,58458:37571,58459:37572,58460:37573,58461:37574,58462:37575,58463:37577,58464:37578,58465:37579,58466:37580,58467:37581,58468:37582,58469:37583,58470:37584,58471:37585,58472:37586,58473:37587,58474:37588,58475:37589,58476:37590,58477:37591,58478:37592,58479:37593,58480:37594,58481:37595,58482:37596,58483:37597,58484:37598,58485:37599,58486:37600,58487:37601,58488:37602,58489:37603,58490:37604,58491:37605,58492:37606,58493:37607,58494:37608,58496:37609,58497:37610,58498:37611,58499:37612,58500:37613,58501:37614,58502:37615,58503:37616,58504:37617,58505:37618,58506:37619,58507:37620,58508:37621,58509:37622,58510:37623,58511:37624,58512:37625,58513:37626,58514:37627,58515:37628,58516:37629,58517:37630,58518:37631,58519:37632,58520:37633,58521:37634,58522:37635,58523:37636,58524:37637,58525:37638,58526:37639,58527:37640,58528:37641,58529:27961,58530:27943,58531:27916,58532:27971,58533:27976,58534:27911,58535:27908,58536:27929,58537:27918,58538:27947,58539:27981,58540:27950,58541:27957,58542:27930,58543:27983,58544:27986,58545:27988,58546:27955,58547:28049,58548:28015,58549:28062,58550:28064,58551:27998,58552:28051,58553:28052,58554:27996,58555:28000,58556:28028,58557:28003,58558:28186,58559:28103,58560:28101,58561:28126,58562:28174,58563:28095,58564:28128,58565:28177,58566:28134,58567:28125,58568:28121,58569:28182,58570:28075,58571:28172,58572:28078,58573:28203,58574:28270,58575:28238,58576:28267,58577:28338,58578:28255,58579:28294,58580:28243,58581:28244,58582:28210,58583:28197,58584:28228,58585:28383,58586:28337,58587:28312,58588:28384,58589:28461,58590:28386,58591:28325,58592:28327,58593:28349,58594:28347,58595:28343,58596:28375,58597:28340,58598:28367,58599:28303,58600:28354,58601:28319,58602:28514,58603:28486,58604:28487,58605:28452,58606:28437,58607:28409,58608:28463,58609:28470,58610:28491,58611:28532,58612:28458,58613:28425,58614:28457,58615:28553,58616:28557,58617:28556,58618:28536,58619:28530,58620:28540,58621:28538,58622:28625,58688:37642,58689:37643,58690:37644,58691:37645,58692:37646,58693:37647,58694:37648,58695:37649,58696:37650,58697:37651,58698:37652,58699:37653,58700:37654,58701:37655,58702:37656,58703:37657,58704:37658,58705:37659,58706:37660,58707:37661,58708:37662,58709:37663,58710:37664,58711:37665,58712:37666,58713:37667,58714:37668,58715:37669,58716:37670,58717:37671,58718:37672,58719:37673,58720:37674,58721:37675,58722:37676,58723:37677,58724:37678,58725:37679,58726:37680,58727:37681,58728:37682,58729:37683,58730:37684,58731:37685,58732:37686,58733:37687,58734:37688,58735:37689,58736:37690,58737:37691,58738:37692,58739:37693,58740:37695,58741:37696,58742:37697,58743:37698,58744:37699,58745:37700,58746:37701,58747:37702,58748:37703,58749:37704,58750:37705,58752:37706,58753:37707,58754:37708,58755:37709,58756:37710,58757:37711,58758:37712,58759:37713,58760:37714,58761:37715,58762:37716,58763:37717,58764:37718,58765:37719,58766:37720,58767:37721,58768:37722,58769:37723,58770:37724,58771:37725,58772:37726,58773:37727,58774:37728,58775:37729,58776:37730,58777:37731,58778:37732,58779:37733,58780:37734,58781:37735,58782:37736,58783:37737,58784:37739,58785:28617,58786:28583,58787:28601,58788:28598,58789:28610,58790:28641,58791:28654,58792:28638,58793:28640,58794:28655,58795:28698,58796:28707,58797:28699,58798:28729,58799:28725,58800:28751,58801:28766,58802:23424,58803:23428,58804:23445,58805:23443,58806:23461,58807:23480,58808:29999,58809:39582,58810:25652,58811:23524,58812:23534,58813:35120,58814:23536,58815:36423,58816:35591,58817:36790,58818:36819,58819:36821,58820:36837,58821:36846,58822:36836,58823:36841,58824:36838,58825:36851,58826:36840,58827:36869,58828:36868,58829:36875,58830:36902,58831:36881,58832:36877,58833:36886,58834:36897,58835:36917,58836:36918,58837:36909,58838:36911,58839:36932,58840:36945,58841:36946,58842:36944,58843:36968,58844:36952,58845:36962,58846:36955,58847:26297,58848:36980,58849:36989,58850:36994,58851:37000,58852:36995,58853:37003,58854:24400,58855:24407,58856:24406,58857:24408,58858:23611,58859:21675,58860:23632,58861:23641,58862:23409,58863:23651,58864:23654,58865:32700,58866:24362,58867:24361,58868:24365,58869:33396,58870:24380,58871:39739,58872:23662,58873:22913,58874:22915,58875:22925,58876:22953,58877:22954,58878:22947,58944:37740,58945:37741,58946:37742,58947:37743,58948:37744,58949:37745,58950:37746,58951:37747,58952:37748,58953:37749,58954:37750,58955:37751,58956:37752,58957:37753,58958:37754,58959:37755,58960:37756,58961:37757,58962:37758,58963:37759,58964:37760,58965:37761,58966:37762,58967:37763,58968:37764,58969:37765,58970:37766,58971:37767,58972:37768,58973:37769,58974:37770,58975:37771,58976:37772,58977:37773,58978:37774,58979:37776,58980:37777,58981:37778,58982:37779,58983:37780,58984:37781,58985:37782,58986:37783,58987:37784,58988:37785,58989:37786,58990:37787,58991:37788,58992:37789,58993:37790,58994:37791,58995:37792,58996:37793,58997:37794,58998:37795,58999:37796,59000:37797,59001:37798,59002:37799,59003:37800,59004:37801,59005:37802,59006:37803,59008:37804,59009:37805,59010:37806,59011:37807,59012:37808,59013:37809,59014:37810,59015:37811,59016:37812,59017:37813,59018:37814,59019:37815,59020:37816,59021:37817,59022:37818,59023:37819,59024:37820,59025:37821,59026:37822,59027:37823,59028:37824,59029:37825,59030:37826,59031:37827,59032:37828,59033:37829,59034:37830,59035:37831,59036:37832,59037:37833,59038:37835,59039:37836,59040:37837,59041:22935,59042:22986,59043:22955,59044:22942,59045:22948,59046:22994,59047:22962,59048:22959,59049:22999,59050:22974,59051:23045,59052:23046,59053:23005,59054:23048,59055:23011,59056:23000,59057:23033,59058:23052,59059:23049,59060:23090,59061:23092,59062:23057,59063:23075,59064:23059,59065:23104,59066:23143,59067:23114,59068:23125,59069:23100,59070:23138,59071:23157,59072:33004,59073:23210,59074:23195,59075:23159,59076:23162,59077:23230,59078:23275,59079:23218,59080:23250,59081:23252,59082:23224,59083:23264,59084:23267,59085:23281,59086:23254,59087:23270,59088:23256,59089:23260,59090:23305,59091:23319,59092:23318,59093:23346,59094:23351,59095:23360,59096:23573,59097:23580,59098:23386,59099:23397,59100:23411,59101:23377,59102:23379,59103:23394,59104:39541,59105:39543,59106:39544,59107:39546,59108:39551,59109:39549,59110:39552,59111:39553,59112:39557,59113:39560,59114:39562,59115:39568,59116:39570,59117:39571,59118:39574,59119:39576,59120:39579,59121:39580,59122:39581,59123:39583,59124:39584,59125:39586,59126:39587,59127:39589,59128:39591,59129:32415,59130:32417,59131:32419,59132:32421,59133:32424,59134:32425,59200:37838,59201:37839,59202:37840,59203:37841,59204:37842,59205:37843,59206:37844,59207:37845,59208:37847,59209:37848,59210:37849,59211:37850,59212:37851,59213:37852,59214:37853,59215:37854,59216:37855,59217:37856,59218:37857,59219:37858,59220:37859,59221:37860,59222:37861,59223:37862,59224:37863,59225:37864,59226:37865,59227:37866,59228:37867,59229:37868,59230:37869,59231:37870,59232:37871,59233:37872,59234:37873,59235:37874,59236:37875,59237:37876,59238:37877,59239:37878,59240:37879,59241:37880,59242:37881,59243:37882,59244:37883,59245:37884,59246:37885,59247:37886,59248:37887,59249:37888,59250:37889,59251:37890,59252:37891,59253:37892,59254:37893,59255:37894,59256:37895,59257:37896,59258:37897,59259:37898,59260:37899,59261:37900,59262:37901,59264:37902,59265:37903,59266:37904,59267:37905,59268:37906,59269:37907,59270:37908,59271:37909,59272:37910,59273:37911,59274:37912,59275:37913,59276:37914,59277:37915,59278:37916,59279:37917,59280:37918,59281:37919,59282:37920,59283:37921,59284:37922,59285:37923,59286:37924,59287:37925,59288:37926,59289:37927,59290:37928,59291:37929,59292:37930,59293:37931,59294:37932,59295:37933,59296:37934,59297:32429,59298:32432,59299:32446,59300:32448,59301:32449,59302:32450,59303:32457,59304:32459,59305:32460,59306:32464,59307:32468,59308:32471,59309:32475,59310:32480,59311:32481,59312:32488,59313:32491,59314:32494,59315:32495,59316:32497,59317:32498,59318:32525,59319:32502,59320:32506,59321:32507,59322:32510,59323:32513,59324:32514,59325:32515,59326:32519,59327:32520,59328:32523,59329:32524,59330:32527,59331:32529,59332:32530,59333:32535,59334:32537,59335:32540,59336:32539,59337:32543,59338:32545,59339:32546,59340:32547,59341:32548,59342:32549,59343:32550,59344:32551,59345:32554,59346:32555,59347:32556,59348:32557,59349:32559,59350:32560,59351:32561,59352:32562,59353:32563,59354:32565,59355:24186,59356:30079,59357:24027,59358:30014,59359:37013,59360:29582,59361:29585,59362:29614,59363:29602,59364:29599,59365:29647,59366:29634,59367:29649,59368:29623,59369:29619,59370:29632,59371:29641,59372:29640,59373:29669,59374:29657,59375:39036,59376:29706,59377:29673,59378:29671,59379:29662,59380:29626,59381:29682,59382:29711,59383:29738,59384:29787,59385:29734,59386:29733,59387:29736,59388:29744,59389:29742,59390:29740,59456:37935,59457:37936,59458:37937,59459:37938,59460:37939,59461:37940,59462:37941,59463:37942,59464:37943,59465:37944,59466:37945,59467:37946,59468:37947,59469:37948,59470:37949,59471:37951,59472:37952,59473:37953,59474:37954,59475:37955,59476:37956,59477:37957,59478:37958,59479:37959,59480:37960,59481:37961,59482:37962,59483:37963,59484:37964,59485:37965,59486:37966,59487:37967,59488:37968,59489:37969,59490:37970,59491:37971,59492:37972,59493:37973,59494:37974,59495:37975,59496:37976,59497:37977,59498:37978,59499:37979,59500:37980,59501:37981,59502:37982,59503:37983,59504:37984,59505:37985,59506:37986,59507:37987,59508:37988,59509:37989,59510:37990,59511:37991,59512:37992,59513:37993,59514:37994,59515:37996,59516:37997,59517:37998,59518:37999,59520:38000,59521:38001,59522:38002,59523:38003,59524:38004,59525:38005,59526:38006,59527:38007,59528:38008,59529:38009,59530:38010,59531:38011,59532:38012,59533:38013,59534:38014,59535:38015,59536:38016,59537:38017,59538:38018,59539:38019,59540:38020,59541:38033,59542:38038,59543:38040,59544:38087,59545:38095,59546:38099,59547:38100,59548:38106,59549:38118,59550:38139,59551:38172,59552:38176,59553:29723,59554:29722,59555:29761,59556:29788,59557:29783,59558:29781,59559:29785,59560:29815,59561:29805,59562:29822,59563:29852,59564:29838,59565:29824,59566:29825,59567:29831,59568:29835,59569:29854,59570:29864,59571:29865,59572:29840,59573:29863,59574:29906,59575:29882,59576:38890,59577:38891,59578:38892,59579:26444,59580:26451,59581:26462,59582:26440,59583:26473,59584:26533,59585:26503,59586:26474,59587:26483,59588:26520,59589:26535,59590:26485,59591:26536,59592:26526,59593:26541,59594:26507,59595:26487,59596:26492,59597:26608,59598:26633,59599:26584,59600:26634,59601:26601,59602:26544,59603:26636,59604:26585,59605:26549,59606:26586,59607:26547,59608:26589,59609:26624,59610:26563,59611:26552,59612:26594,59613:26638,59614:26561,59615:26621,59616:26674,59617:26675,59618:26720,59619:26721,59620:26702,59621:26722,59622:26692,59623:26724,59624:26755,59625:26653,59626:26709,59627:26726,59628:26689,59629:26727,59630:26688,59631:26686,59632:26698,59633:26697,59634:26665,59635:26805,59636:26767,59637:26740,59638:26743,59639:26771,59640:26731,59641:26818,59642:26990,59643:26876,59644:26911,59645:26912,59646:26873,59712:38183,59713:38195,59714:38205,59715:38211,59716:38216,59717:38219,59718:38229,59719:38234,59720:38240,59721:38254,59722:38260,59723:38261,59724:38263,59725:38264,59726:38265,59727:38266,59728:38267,59729:38268,59730:38269,59731:38270,59732:38272,59733:38273,59734:38274,59735:38275,59736:38276,59737:38277,59738:38278,59739:38279,59740:38280,59741:38281,59742:38282,59743:38283,59744:38284,59745:38285,59746:38286,59747:38287,59748:38288,59749:38289,59750:38290,59751:38291,59752:38292,59753:38293,59754:38294,59755:38295,59756:38296,59757:38297,59758:38298,59759:38299,59760:38300,59761:38301,59762:38302,59763:38303,59764:38304,59765:38305,59766:38306,59767:38307,59768:38308,59769:38309,59770:38310,59771:38311,59772:38312,59773:38313,59774:38314,59776:38315,59777:38316,59778:38317,59779:38318,59780:38319,59781:38320,59782:38321,59783:38322,59784:38323,59785:38324,59786:38325,59787:38326,59788:38327,59789:38328,59790:38329,59791:38330,59792:38331,59793:38332,59794:38333,59795:38334,59796:38335,59797:38336,59798:38337,59799:38338,59800:38339,59801:38340,59802:38341,59803:38342,59804:38343,59805:38344,59806:38345,59807:38346,59808:38347,59809:26916,59810:26864,59811:26891,59812:26881,59813:26967,59814:26851,59815:26896,59816:26993,59817:26937,59818:26976,59819:26946,59820:26973,59821:27012,59822:26987,59823:27008,59824:27032,59825:27000,59826:26932,59827:27084,59828:27015,59829:27016,59830:27086,59831:27017,59832:26982,59833:26979,59834:27001,59835:27035,59836:27047,59837:27067,59838:27051,59839:27053,59840:27092,59841:27057,59842:27073,59843:27082,59844:27103,59845:27029,59846:27104,59847:27021,59848:27135,59849:27183,59850:27117,59851:27159,59852:27160,59853:27237,59854:27122,59855:27204,59856:27198,59857:27296,59858:27216,59859:27227,59860:27189,59861:27278,59862:27257,59863:27197,59864:27176,59865:27224,59866:27260,59867:27281,59868:27280,59869:27305,59870:27287,59871:27307,59872:29495,59873:29522,59874:27521,59875:27522,59876:27527,59877:27524,59878:27538,59879:27539,59880:27533,59881:27546,59882:27547,59883:27553,59884:27562,59885:36715,59886:36717,59887:36721,59888:36722,59889:36723,59890:36725,59891:36726,59892:36728,59893:36727,59894:36729,59895:36730,59896:36732,59897:36734,59898:36737,59899:36738,59900:36740,59901:36743,59902:36747,59968:38348,59969:38349,59970:38350,59971:38351,59972:38352,59973:38353,59974:38354,59975:38355,59976:38356,59977:38357,59978:38358,59979:38359,59980:38360,59981:38361,59982:38362,59983:38363,59984:38364,59985:38365,59986:38366,59987:38367,59988:38368,59989:38369,59990:38370,59991:38371,59992:38372,59993:38373,59994:38374,59995:38375,59996:38380,59997:38399,59998:38407,59999:38419,60000:38424,60001:38427,60002:38430,60003:38432,60004:38435,60005:38436,60006:38437,60007:38438,60008:38439,60009:38440,60010:38441,60011:38443,60012:38444,60013:38445,60014:38447,60015:38448,60016:38455,60017:38456,60018:38457,60019:38458,60020:38462,60021:38465,60022:38467,60023:38474,60024:38478,60025:38479,60026:38481,60027:38482,60028:38483,60029:38486,60030:38487,60032:38488,60033:38489,60034:38490,60035:38492,60036:38493,60037:38494,60038:38496,60039:38499,60040:38501,60041:38502,60042:38507,60043:38509,60044:38510,60045:38511,60046:38512,60047:38513,60048:38515,60049:38520,60050:38521,60051:38522,60052:38523,60053:38524,60054:38525,60055:38526,60056:38527,60057:38528,60058:38529,60059:38530,60060:38531,60061:38532,60062:38535,60063:38537,60064:38538,60065:36749,60066:36750,60067:36751,60068:36760,60069:36762,60070:36558,60071:25099,60072:25111,60073:25115,60074:25119,60075:25122,60076:25121,60077:25125,60078:25124,60079:25132,60080:33255,60081:29935,60082:29940,60083:29951,60084:29967,60085:29969,60086:29971,60087:25908,60088:26094,60089:26095,60090:26096,60091:26122,60092:26137,60093:26482,60094:26115,60095:26133,60096:26112,60097:28805,60098:26359,60099:26141,60100:26164,60101:26161,60102:26166,60103:26165,60104:32774,60105:26207,60106:26196,60107:26177,60108:26191,60109:26198,60110:26209,60111:26199,60112:26231,60113:26244,60114:26252,60115:26279,60116:26269,60117:26302,60118:26331,60119:26332,60120:26342,60121:26345,60122:36146,60123:36147,60124:36150,60125:36155,60126:36157,60127:36160,60128:36165,60129:36166,60130:36168,60131:36169,60132:36167,60133:36173,60134:36181,60135:36185,60136:35271,60137:35274,60138:35275,60139:35276,60140:35278,60141:35279,60142:35280,60143:35281,60144:29294,60145:29343,60146:29277,60147:29286,60148:29295,60149:29310,60150:29311,60151:29316,60152:29323,60153:29325,60154:29327,60155:29330,60156:25352,60157:25394,60158:25520,60224:38540,60225:38542,60226:38545,60227:38546,60228:38547,60229:38549,60230:38550,60231:38554,60232:38555,60233:38557,60234:38558,60235:38559,60236:38560,60237:38561,60238:38562,60239:38563,60240:38564,60241:38565,60242:38566,60243:38568,60244:38569,60245:38570,60246:38571,60247:38572,60248:38573,60249:38574,60250:38575,60251:38577,60252:38578,60253:38580,60254:38581,60255:38583,60256:38584,60257:38586,60258:38587,60259:38591,60260:38594,60261:38595,60262:38600,60263:38602,60264:38603,60265:38608,60266:38609,60267:38611,60268:38612,60269:38614,60270:38615,60271:38616,60272:38617,60273:38618,60274:38619,60275:38620,60276:38621,60277:38622,60278:38623,60279:38625,60280:38626,60281:38627,60282:38628,60283:38629,60284:38630,60285:38631,60286:38635,60288:38636,60289:38637,60290:38638,60291:38640,60292:38641,60293:38642,60294:38644,60295:38645,60296:38648,60297:38650,60298:38651,60299:38652,60300:38653,60301:38655,60302:38658,60303:38659,60304:38661,60305:38666,60306:38667,60307:38668,60308:38672,60309:38673,60310:38674,60311:38676,60312:38677,60313:38679,60314:38680,60315:38681,60316:38682,60317:38683,60318:38685,60319:38687,60320:38688,60321:25663,60322:25816,60323:32772,60324:27626,60325:27635,60326:27645,60327:27637,60328:27641,60329:27653,60330:27655,60331:27654,60332:27661,60333:27669,60334:27672,60335:27673,60336:27674,60337:27681,60338:27689,60339:27684,60340:27690,60341:27698,60342:25909,60343:25941,60344:25963,60345:29261,60346:29266,60347:29270,60348:29232,60349:34402,60350:21014,60351:32927,60352:32924,60353:32915,60354:32956,60355:26378,60356:32957,60357:32945,60358:32939,60359:32941,60360:32948,60361:32951,60362:32999,60363:33000,60364:33001,60365:33002,60366:32987,60367:32962,60368:32964,60369:32985,60370:32973,60371:32983,60372:26384,60373:32989,60374:33003,60375:33009,60376:33012,60377:33005,60378:33037,60379:33038,60380:33010,60381:33020,60382:26389,60383:33042,60384:35930,60385:33078,60386:33054,60387:33068,60388:33048,60389:33074,60390:33096,60391:33100,60392:33107,60393:33140,60394:33113,60395:33114,60396:33137,60397:33120,60398:33129,60399:33148,60400:33149,60401:33133,60402:33127,60403:22605,60404:23221,60405:33160,60406:33154,60407:33169,60408:28373,60409:33187,60410:33194,60411:33228,60412:26406,60413:33226,60414:33211,60480:38689,60481:38690,60482:38691,60483:38692,60484:38693,60485:38694,60486:38695,60487:38696,60488:38697,60489:38699,60490:38700,60491:38702,60492:38703,60493:38705,60494:38707,60495:38708,60496:38709,60497:38710,60498:38711,60499:38714,60500:38715,60501:38716,60502:38717,60503:38719,60504:38720,60505:38721,60506:38722,60507:38723,60508:38724,60509:38725,60510:38726,60511:38727,60512:38728,60513:38729,60514:38730,60515:38731,60516:38732,60517:38733,60518:38734,60519:38735,60520:38736,60521:38737,60522:38740,60523:38741,60524:38743,60525:38744,60526:38746,60527:38748,60528:38749,60529:38751,60530:38755,60531:38756,60532:38758,60533:38759,60534:38760,60535:38762,60536:38763,60537:38764,60538:38765,60539:38766,60540:38767,60541:38768,60542:38769,60544:38770,60545:38773,60546:38775,60547:38776,60548:38777,60549:38778,60550:38779,60551:38781,60552:38782,60553:38783,60554:38784,60555:38785,60556:38786,60557:38787,60558:38788,60559:38790,60560:38791,60561:38792,60562:38793,60563:38794,60564:38796,60565:38798,60566:38799,60567:38800,60568:38803,60569:38805,60570:38806,60571:38807,60572:38809,60573:38810,60574:38811,60575:38812,60576:38813,60577:33217,60578:33190,60579:27428,60580:27447,60581:27449,60582:27459,60583:27462,60584:27481,60585:39121,60586:39122,60587:39123,60588:39125,60589:39129,60590:39130,60591:27571,60592:24384,60593:27586,60594:35315,60595:26000,60596:40785,60597:26003,60598:26044,60599:26054,60600:26052,60601:26051,60602:26060,60603:26062,60604:26066,60605:26070,60606:28800,60607:28828,60608:28822,60609:28829,60610:28859,60611:28864,60612:28855,60613:28843,60614:28849,60615:28904,60616:28874,60617:28944,60618:28947,60619:28950,60620:28975,60621:28977,60622:29043,60623:29020,60624:29032,60625:28997,60626:29042,60627:29002,60628:29048,60629:29050,60630:29080,60631:29107,60632:29109,60633:29096,60634:29088,60635:29152,60636:29140,60637:29159,60638:29177,60639:29213,60640:29224,60641:28780,60642:28952,60643:29030,60644:29113,60645:25150,60646:25149,60647:25155,60648:25160,60649:25161,60650:31035,60651:31040,60652:31046,60653:31049,60654:31067,60655:31068,60656:31059,60657:31066,60658:31074,60659:31063,60660:31072,60661:31087,60662:31079,60663:31098,60664:31109,60665:31114,60666:31130,60667:31143,60668:31155,60669:24529,60670:24528,60736:38814,60737:38815,60738:38817,60739:38818,60740:38820,60741:38821,60742:38822,60743:38823,60744:38824,60745:38825,60746:38826,60747:38828,60748:38830,60749:38832,60750:38833,60751:38835,60752:38837,60753:38838,60754:38839,60755:38840,60756:38841,60757:38842,60758:38843,60759:38844,60760:38845,60761:38846,60762:38847,60763:38848,60764:38849,60765:38850,60766:38851,60767:38852,60768:38853,60769:38854,60770:38855,60771:38856,60772:38857,60773:38858,60774:38859,60775:38860,60776:38861,60777:38862,60778:38863,60779:38864,60780:38865,60781:38866,60782:38867,60783:38868,60784:38869,60785:38870,60786:38871,60787:38872,60788:38873,60789:38874,60790:38875,60791:38876,60792:38877,60793:38878,60794:38879,60795:38880,60796:38881,60797:38882,60798:38883,60800:38884,60801:38885,60802:38888,60803:38894,60804:38895,60805:38896,60806:38897,60807:38898,60808:38900,60809:38903,60810:38904,60811:38905,60812:38906,60813:38907,60814:38908,60815:38909,60816:38910,60817:38911,60818:38912,60819:38913,60820:38914,60821:38915,60822:38916,60823:38917,60824:38918,60825:38919,60826:38920,60827:38921,60828:38922,60829:38923,60830:38924,60831:38925,60832:38926,60833:24636,60834:24669,60835:24666,60836:24679,60837:24641,60838:24665,60839:24675,60840:24747,60841:24838,60842:24845,60843:24925,60844:25001,60845:24989,60846:25035,60847:25041,60848:25094,60849:32896,60850:32895,60851:27795,60852:27894,60853:28156,60854:30710,60855:30712,60856:30720,60857:30729,60858:30743,60859:30744,60860:30737,60861:26027,60862:30765,60863:30748,60864:30749,60865:30777,60866:30778,60867:30779,60868:30751,60869:30780,60870:30757,60871:30764,60872:30755,60873:30761,60874:30798,60875:30829,60876:30806,60877:30807,60878:30758,60879:30800,60880:30791,60881:30796,60882:30826,60883:30875,60884:30867,60885:30874,60886:30855,60887:30876,60888:30881,60889:30883,60890:30898,60891:30905,60892:30885,60893:30932,60894:30937,60895:30921,60896:30956,60897:30962,60898:30981,60899:30964,60900:30995,60901:31012,60902:31006,60903:31028,60904:40859,60905:40697,60906:40699,60907:40700,60908:30449,60909:30468,60910:30477,60911:30457,60912:30471,60913:30472,60914:30490,60915:30498,60916:30489,60917:30509,60918:30502,60919:30517,60920:30520,60921:30544,60922:30545,60923:30535,60924:30531,60925:30554,60926:30568,60992:38927,60993:38928,60994:38929,60995:38930,60996:38931,60997:38932,60998:38933,60999:38934,61000:38935,61001:38936,61002:38937,61003:38938,61004:38939,61005:38940,61006:38941,61007:38942,61008:38943,61009:38944,61010:38945,61011:38946,61012:38947,61013:38948,61014:38949,61015:38950,61016:38951,61017:38952,61018:38953,61019:38954,61020:38955,61021:38956,61022:38957,61023:38958,61024:38959,61025:38960,61026:38961,61027:38962,61028:38963,61029:38964,61030:38965,61031:38966,61032:38967,61033:38968,61034:38969,61035:38970,61036:38971,61037:38972,61038:38973,61039:38974,61040:38975,61041:38976,61042:38977,61043:38978,61044:38979,61045:38980,61046:38981,61047:38982,61048:38983,61049:38984,61050:38985,61051:38986,61052:38987,61053:38988,61054:38989,61056:38990,61057:38991,61058:38992,61059:38993,61060:38994,61061:38995,61062:38996,61063:38997,61064:38998,61065:38999,61066:39000,61067:39001,61068:39002,61069:39003,61070:39004,61071:39005,61072:39006,61073:39007,61074:39008,61075:39009,61076:39010,61077:39011,61078:39012,61079:39013,61080:39014,61081:39015,61082:39016,61083:39017,61084:39018,61085:39019,61086:39020,61087:39021,61088:39022,61089:30562,61090:30565,61091:30591,61092:30605,61093:30589,61094:30592,61095:30604,61096:30609,61097:30623,61098:30624,61099:30640,61100:30645,61101:30653,61102:30010,61103:30016,61104:30030,61105:30027,61106:30024,61107:30043,61108:30066,61109:30073,61110:30083,61111:32600,61112:32609,61113:32607,61114:35400,61115:32616,61116:32628,61117:32625,61118:32633,61119:32641,61120:32638,61121:30413,61122:30437,61123:34866,61124:38021,61125:38022,61126:38023,61127:38027,61128:38026,61129:38028,61130:38029,61131:38031,61132:38032,61133:38036,61134:38039,61135:38037,61136:38042,61137:38043,61138:38044,61139:38051,61140:38052,61141:38059,61142:38058,61143:38061,61144:38060,61145:38063,61146:38064,61147:38066,61148:38068,61149:38070,61150:38071,61151:38072,61152:38073,61153:38074,61154:38076,61155:38077,61156:38079,61157:38084,61158:38088,61159:38089,61160:38090,61161:38091,61162:38092,61163:38093,61164:38094,61165:38096,61166:38097,61167:38098,61168:38101,61169:38102,61170:38103,61171:38105,61172:38104,61173:38107,61174:38110,61175:38111,61176:38112,61177:38114,61178:38116,61179:38117,61180:38119,61181:38120,61182:38122,61248:39023,61249:39024,61250:39025,61251:39026,61252:39027,61253:39028,61254:39051,61255:39054,61256:39058,61257:39061,61258:39065,61259:39075,61260:39080,61261:39081,61262:39082,61263:39083,61264:39084,61265:39085,61266:39086,61267:39087,61268:39088,61269:39089,61270:39090,61271:39091,61272:39092,61273:39093,61274:39094,61275:39095,61276:39096,61277:39097,61278:39098,61279:39099,61280:39100,61281:39101,61282:39102,61283:39103,61284:39104,61285:39105,61286:39106,61287:39107,61288:39108,61289:39109,61290:39110,61291:39111,61292:39112,61293:39113,61294:39114,61295:39115,61296:39116,61297:39117,61298:39119,61299:39120,61300:39124,61301:39126,61302:39127,61303:39131,61304:39132,61305:39133,61306:39136,61307:39137,61308:39138,61309:39139,61310:39140,61312:39141,61313:39142,61314:39145,61315:39146,61316:39147,61317:39148,61318:39149,61319:39150,61320:39151,61321:39152,61322:39153,61323:39154,61324:39155,61325:39156,61326:39157,61327:39158,61328:39159,61329:39160,61330:39161,61331:39162,61332:39163,61333:39164,61334:39165,61335:39166,61336:39167,61337:39168,61338:39169,61339:39170,61340:39171,61341:39172,61342:39173,61343:39174,61344:39175,61345:38121,61346:38123,61347:38126,61348:38127,61349:38131,61350:38132,61351:38133,61352:38135,61353:38137,61354:38140,61355:38141,61356:38143,61357:38147,61358:38146,61359:38150,61360:38151,61361:38153,61362:38154,61363:38157,61364:38158,61365:38159,61366:38162,61367:38163,61368:38164,61369:38165,61370:38166,61371:38168,61372:38171,61373:38173,61374:38174,61375:38175,61376:38178,61377:38186,61378:38187,61379:38185,61380:38188,61381:38193,61382:38194,61383:38196,61384:38198,61385:38199,61386:38200,61387:38204,61388:38206,61389:38207,61390:38210,61391:38197,61392:38212,61393:38213,61394:38214,61395:38217,61396:38220,61397:38222,61398:38223,61399:38226,61400:38227,61401:38228,61402:38230,61403:38231,61404:38232,61405:38233,61406:38235,61407:38238,61408:38239,61409:38237,61410:38241,61411:38242,61412:38244,61413:38245,61414:38246,61415:38247,61416:38248,61417:38249,61418:38250,61419:38251,61420:38252,61421:38255,61422:38257,61423:38258,61424:38259,61425:38202,61426:30695,61427:30700,61428:38601,61429:31189,61430:31213,61431:31203,61432:31211,61433:31238,61434:23879,61435:31235,61436:31234,61437:31262,61438:31252,61504:39176,61505:39177,61506:39178,61507:39179,61508:39180,61509:39182,61510:39183,61511:39185,61512:39186,61513:39187,61514:39188,61515:39189,61516:39190,61517:39191,61518:39192,61519:39193,61520:39194,61521:39195,61522:39196,61523:39197,61524:39198,61525:39199,61526:39200,61527:39201,61528:39202,61529:39203,61530:39204,61531:39205,61532:39206,61533:39207,61534:39208,61535:39209,61536:39210,61537:39211,61538:39212,61539:39213,61540:39215,61541:39216,61542:39217,61543:39218,61544:39219,61545:39220,61546:39221,61547:39222,61548:39223,61549:39224,61550:39225,61551:39226,61552:39227,61553:39228,61554:39229,61555:39230,61556:39231,61557:39232,61558:39233,61559:39234,61560:39235,61561:39236,61562:39237,61563:39238,61564:39239,61565:39240,61566:39241,61568:39242,61569:39243,61570:39244,61571:39245,61572:39246,61573:39247,61574:39248,61575:39249,61576:39250,61577:39251,61578:39254,61579:39255,61580:39256,61581:39257,61582:39258,61583:39259,61584:39260,61585:39261,61586:39262,61587:39263,61588:39264,61589:39265,61590:39266,61591:39268,61592:39270,61593:39283,61594:39288,61595:39289,61596:39291,61597:39294,61598:39298,61599:39299,61600:39305,61601:31289,61602:31287,61603:31313,61604:40655,61605:39333,61606:31344,61607:30344,61608:30350,61609:30355,61610:30361,61611:30372,61612:29918,61613:29920,61614:29996,61615:40480,61616:40482,61617:40488,61618:40489,61619:40490,61620:40491,61621:40492,61622:40498,61623:40497,61624:40502,61625:40504,61626:40503,61627:40505,61628:40506,61629:40510,61630:40513,61631:40514,61632:40516,61633:40518,61634:40519,61635:40520,61636:40521,61637:40523,61638:40524,61639:40526,61640:40529,61641:40533,61642:40535,61643:40538,61644:40539,61645:40540,61646:40542,61647:40547,61648:40550,61649:40551,61650:40552,61651:40553,61652:40554,61653:40555,61654:40556,61655:40561,61656:40557,61657:40563,61658:30098,61659:30100,61660:30102,61661:30112,61662:30109,61663:30124,61664:30115,61665:30131,61666:30132,61667:30136,61668:30148,61669:30129,61670:30128,61671:30147,61672:30146,61673:30166,61674:30157,61675:30179,61676:30184,61677:30182,61678:30180,61679:30187,61680:30183,61681:30211,61682:30193,61683:30204,61684:30207,61685:30224,61686:30208,61687:30213,61688:30220,61689:30231,61690:30218,61691:30245,61692:30232,61693:30229,61694:30233,61760:39308,61761:39310,61762:39322,61763:39323,61764:39324,61765:39325,61766:39326,61767:39327,61768:39328,61769:39329,61770:39330,61771:39331,61772:39332,61773:39334,61774:39335,61775:39337,61776:39338,61777:39339,61778:39340,61779:39341,61780:39342,61781:39343,61782:39344,61783:39345,61784:39346,61785:39347,61786:39348,61787:39349,61788:39350,61789:39351,61790:39352,61791:39353,61792:39354,61793:39355,61794:39356,61795:39357,61796:39358,61797:39359,61798:39360,61799:39361,61800:39362,61801:39363,61802:39364,61803:39365,61804:39366,61805:39367,61806:39368,61807:39369,61808:39370,61809:39371,61810:39372,61811:39373,61812:39374,61813:39375,61814:39376,61815:39377,61816:39378,61817:39379,61818:39380,61819:39381,61820:39382,61821:39383,61822:39384,61824:39385,61825:39386,61826:39387,61827:39388,61828:39389,61829:39390,61830:39391,61831:39392,61832:39393,61833:39394,61834:39395,61835:39396,61836:39397,61837:39398,61838:39399,61839:39400,61840:39401,61841:39402,61842:39403,61843:39404,61844:39405,61845:39406,61846:39407,61847:39408,61848:39409,61849:39410,61850:39411,61851:39412,61852:39413,61853:39414,61854:39415,61855:39416,61856:39417,61857:30235,61858:30268,61859:30242,61860:30240,61861:30272,61862:30253,61863:30256,61864:30271,61865:30261,61866:30275,61867:30270,61868:30259,61869:30285,61870:30302,61871:30292,61872:30300,61873:30294,61874:30315,61875:30319,61876:32714,61877:31462,61878:31352,61879:31353,61880:31360,61881:31366,61882:31368,61883:31381,61884:31398,61885:31392,61886:31404,61887:31400,61888:31405,61889:31411,61890:34916,61891:34921,61892:34930,61893:34941,61894:34943,61895:34946,61896:34978,61897:35014,61898:34999,61899:35004,61900:35017,61901:35042,61902:35022,61903:35043,61904:35045,61905:35057,61906:35098,61907:35068,61908:35048,61909:35070,61910:35056,61911:35105,61912:35097,61913:35091,61914:35099,61915:35082,61916:35124,61917:35115,61918:35126,61919:35137,61920:35174,61921:35195,61922:30091,61923:32997,61924:30386,61925:30388,61926:30684,61927:32786,61928:32788,61929:32790,61930:32796,61931:32800,61932:32802,61933:32805,61934:32806,61935:32807,61936:32809,61937:32808,61938:32817,61939:32779,61940:32821,61941:32835,61942:32838,61943:32845,61944:32850,61945:32873,61946:32881,61947:35203,61948:39032,61949:39040,61950:39043,62016:39418,62017:39419,62018:39420,62019:39421,62020:39422,62021:39423,62022:39424,62023:39425,62024:39426,62025:39427,62026:39428,62027:39429,62028:39430,62029:39431,62030:39432,62031:39433,62032:39434,62033:39435,62034:39436,62035:39437,62036:39438,62037:39439,62038:39440,62039:39441,62040:39442,62041:39443,62042:39444,62043:39445,62044:39446,62045:39447,62046:39448,62047:39449,62048:39450,62049:39451,62050:39452,62051:39453,62052:39454,62053:39455,62054:39456,62055:39457,62056:39458,62057:39459,62058:39460,62059:39461,62060:39462,62061:39463,62062:39464,62063:39465,62064:39466,62065:39467,62066:39468,62067:39469,62068:39470,62069:39471,62070:39472,62071:39473,62072:39474,62073:39475,62074:39476,62075:39477,62076:39478,62077:39479,62078:39480,62080:39481,62081:39482,62082:39483,62083:39484,62084:39485,62085:39486,62086:39487,62087:39488,62088:39489,62089:39490,62090:39491,62091:39492,62092:39493,62093:39494,62094:39495,62095:39496,62096:39497,62097:39498,62098:39499,62099:39500,62100:39501,62101:39502,62102:39503,62103:39504,62104:39505,62105:39506,62106:39507,62107:39508,62108:39509,62109:39510,62110:39511,62111:39512,62112:39513,62113:39049,62114:39052,62115:39053,62116:39055,62117:39060,62118:39066,62119:39067,62120:39070,62121:39071,62122:39073,62123:39074,62124:39077,62125:39078,62126:34381,62127:34388,62128:34412,62129:34414,62130:34431,62131:34426,62132:34428,62133:34427,62134:34472,62135:34445,62136:34443,62137:34476,62138:34461,62139:34471,62140:34467,62141:34474,62142:34451,62143:34473,62144:34486,62145:34500,62146:34485,62147:34510,62148:34480,62149:34490,62150:34481,62151:34479,62152:34505,62153:34511,62154:34484,62155:34537,62156:34545,62157:34546,62158:34541,62159:34547,62160:34512,62161:34579,62162:34526,62163:34548,62164:34527,62165:34520,62166:34513,62167:34563,62168:34567,62169:34552,62170:34568,62171:34570,62172:34573,62173:34569,62174:34595,62175:34619,62176:34590,62177:34597,62178:34606,62179:34586,62180:34622,62181:34632,62182:34612,62183:34609,62184:34601,62185:34615,62186:34623,62187:34690,62188:34594,62189:34685,62190:34686,62191:34683,62192:34656,62193:34672,62194:34636,62195:34670,62196:34699,62197:34643,62198:34659,62199:34684,62200:34660,62201:34649,62202:34661,62203:34707,62204:34735,62205:34728,62206:34770,62272:39514,62273:39515,62274:39516,62275:39517,62276:39518,62277:39519,62278:39520,62279:39521,62280:39522,62281:39523,62282:39524,62283:39525,62284:39526,62285:39527,62286:39528,62287:39529,62288:39530,62289:39531,62290:39538,62291:39555,62292:39561,62293:39565,62294:39566,62295:39572,62296:39573,62297:39577,62298:39590,62299:39593,62300:39594,62301:39595,62302:39596,62303:39597,62304:39598,62305:39599,62306:39602,62307:39603,62308:39604,62309:39605,62310:39609,62311:39611,62312:39613,62313:39614,62314:39615,62315:39619,62316:39620,62317:39622,62318:39623,62319:39624,62320:39625,62321:39626,62322:39629,62323:39630,62324:39631,62325:39632,62326:39634,62327:39636,62328:39637,62329:39638,62330:39639,62331:39641,62332:39642,62333:39643,62334:39644,62336:39645,62337:39646,62338:39648,62339:39650,62340:39651,62341:39652,62342:39653,62343:39655,62344:39656,62345:39657,62346:39658,62347:39660,62348:39662,62349:39664,62350:39665,62351:39666,62352:39667,62353:39668,62354:39669,62355:39670,62356:39671,62357:39672,62358:39674,62359:39676,62360:39677,62361:39678,62362:39679,62363:39680,62364:39681,62365:39682,62366:39684,62367:39685,62368:39686,62369:34758,62370:34696,62371:34693,62372:34733,62373:34711,62374:34691,62375:34731,62376:34789,62377:34732,62378:34741,62379:34739,62380:34763,62381:34771,62382:34749,62383:34769,62384:34752,62385:34762,62386:34779,62387:34794,62388:34784,62389:34798,62390:34838,62391:34835,62392:34814,62393:34826,62394:34843,62395:34849,62396:34873,62397:34876,62398:32566,62399:32578,62400:32580,62401:32581,62402:33296,62403:31482,62404:31485,62405:31496,62406:31491,62407:31492,62408:31509,62409:31498,62410:31531,62411:31503,62412:31559,62413:31544,62414:31530,62415:31513,62416:31534,62417:31537,62418:31520,62419:31525,62420:31524,62421:31539,62422:31550,62423:31518,62424:31576,62425:31578,62426:31557,62427:31605,62428:31564,62429:31581,62430:31584,62431:31598,62432:31611,62433:31586,62434:31602,62435:31601,62436:31632,62437:31654,62438:31655,62439:31672,62440:31660,62441:31645,62442:31656,62443:31621,62444:31658,62445:31644,62446:31650,62447:31659,62448:31668,62449:31697,62450:31681,62451:31692,62452:31709,62453:31706,62454:31717,62455:31718,62456:31722,62457:31756,62458:31742,62459:31740,62460:31759,62461:31766,62462:31755,62528:39687,62529:39689,62530:39690,62531:39691,62532:39692,62533:39693,62534:39694,62535:39696,62536:39697,62537:39698,62538:39700,62539:39701,62540:39702,62541:39703,62542:39704,62543:39705,62544:39706,62545:39707,62546:39708,62547:39709,62548:39710,62549:39712,62550:39713,62551:39714,62552:39716,62553:39717,62554:39718,62555:39719,62556:39720,62557:39721,62558:39722,62559:39723,62560:39724,62561:39725,62562:39726,62563:39728,62564:39729,62565:39731,62566:39732,62567:39733,62568:39734,62569:39735,62570:39736,62571:39737,62572:39738,62573:39741,62574:39742,62575:39743,62576:39744,62577:39750,62578:39754,62579:39755,62580:39756,62581:39758,62582:39760,62583:39762,62584:39763,62585:39765,62586:39766,62587:39767,62588:39768,62589:39769,62590:39770,62592:39771,62593:39772,62594:39773,62595:39774,62596:39775,62597:39776,62598:39777,62599:39778,62600:39779,62601:39780,62602:39781,62603:39782,62604:39783,62605:39784,62606:39785,62607:39786,62608:39787,62609:39788,62610:39789,62611:39790,62612:39791,62613:39792,62614:39793,62615:39794,62616:39795,62617:39796,62618:39797,62619:39798,62620:39799,62621:39800,62622:39801,62623:39802,62624:39803,62625:31775,62626:31786,62627:31782,62628:31800,62629:31809,62630:31808,62631:33278,62632:33281,62633:33282,62634:33284,62635:33260,62636:34884,62637:33313,62638:33314,62639:33315,62640:33325,62641:33327,62642:33320,62643:33323,62644:33336,62645:33339,62646:33331,62647:33332,62648:33342,62649:33348,62650:33353,62651:33355,62652:33359,62653:33370,62654:33375,62655:33384,62656:34942,62657:34949,62658:34952,62659:35032,62660:35039,62661:35166,62662:32669,62663:32671,62664:32679,62665:32687,62666:32688,62667:32690,62668:31868,62669:25929,62670:31889,62671:31901,62672:31900,62673:31902,62674:31906,62675:31922,62676:31932,62677:31933,62678:31937,62679:31943,62680:31948,62681:31949,62682:31944,62683:31941,62684:31959,62685:31976,62686:33390,62687:26280,62688:32703,62689:32718,62690:32725,62691:32741,62692:32737,62693:32742,62694:32745,62695:32750,62696:32755,62697:31992,62698:32119,62699:32166,62700:32174,62701:32327,62702:32411,62703:40632,62704:40628,62705:36211,62706:36228,62707:36244,62708:36241,62709:36273,62710:36199,62711:36205,62712:35911,62713:35913,62714:37194,62715:37200,62716:37198,62717:37199,62718:37220,62784:39804,62785:39805,62786:39806,62787:39807,62788:39808,62789:39809,62790:39810,62791:39811,62792:39812,62793:39813,62794:39814,62795:39815,62796:39816,62797:39817,62798:39818,62799:39819,62800:39820,62801:39821,62802:39822,62803:39823,62804:39824,62805:39825,62806:39826,62807:39827,62808:39828,62809:39829,62810:39830,62811:39831,62812:39832,62813:39833,62814:39834,62815:39835,62816:39836,62817:39837,62818:39838,62819:39839,62820:39840,62821:39841,62822:39842,62823:39843,62824:39844,62825:39845,62826:39846,62827:39847,62828:39848,62829:39849,62830:39850,62831:39851,62832:39852,62833:39853,62834:39854,62835:39855,62836:39856,62837:39857,62838:39858,62839:39859,62840:39860,62841:39861,62842:39862,62843:39863,62844:39864,62845:39865,62846:39866,62848:39867,62849:39868,62850:39869,62851:39870,62852:39871,62853:39872,62854:39873,62855:39874,62856:39875,62857:39876,62858:39877,62859:39878,62860:39879,62861:39880,62862:39881,62863:39882,62864:39883,62865:39884,62866:39885,62867:39886,62868:39887,62869:39888,62870:39889,62871:39890,62872:39891,62873:39892,62874:39893,62875:39894,62876:39895,62877:39896,62878:39897,62879:39898,62880:39899,62881:37218,62882:37217,62883:37232,62884:37225,62885:37231,62886:37245,62887:37246,62888:37234,62889:37236,62890:37241,62891:37260,62892:37253,62893:37264,62894:37261,62895:37265,62896:37282,62897:37283,62898:37290,62899:37293,62900:37294,62901:37295,62902:37301,62903:37300,62904:37306,62905:35925,62906:40574,62907:36280,62908:36331,62909:36357,62910:36441,62911:36457,62912:36277,62913:36287,62914:36284,62915:36282,62916:36292,62917:36310,62918:36311,62919:36314,62920:36318,62921:36302,62922:36303,62923:36315,62924:36294,62925:36332,62926:36343,62927:36344,62928:36323,62929:36345,62930:36347,62931:36324,62932:36361,62933:36349,62934:36372,62935:36381,62936:36383,62937:36396,62938:36398,62939:36387,62940:36399,62941:36410,62942:36416,62943:36409,62944:36405,62945:36413,62946:36401,62947:36425,62948:36417,62949:36418,62950:36433,62951:36434,62952:36426,62953:36464,62954:36470,62955:36476,62956:36463,62957:36468,62958:36485,62959:36495,62960:36500,62961:36496,62962:36508,62963:36510,62964:35960,62965:35970,62966:35978,62967:35973,62968:35992,62969:35988,62970:26011,62971:35286,62972:35294,62973:35290,62974:35292,63040:39900,63041:39901,63042:39902,63043:39903,63044:39904,63045:39905,63046:39906,63047:39907,63048:39908,63049:39909,63050:39910,63051:39911,63052:39912,63053:39913,63054:39914,63055:39915,63056:39916,63057:39917,63058:39918,63059:39919,63060:39920,63061:39921,63062:39922,63063:39923,63064:39924,63065:39925,63066:39926,63067:39927,63068:39928,63069:39929,63070:39930,63071:39931,63072:39932,63073:39933,63074:39934,63075:39935,63076:39936,63077:39937,63078:39938,63079:39939,63080:39940,63081:39941,63082:39942,63083:39943,63084:39944,63085:39945,63086:39946,63087:39947,63088:39948,63089:39949,63090:39950,63091:39951,63092:39952,63093:39953,63094:39954,63095:39955,63096:39956,63097:39957,63098:39958,63099:39959,63100:39960,63101:39961,63102:39962,63104:39963,63105:39964,63106:39965,63107:39966,63108:39967,63109:39968,63110:39969,63111:39970,63112:39971,63113:39972,63114:39973,63115:39974,63116:39975,63117:39976,63118:39977,63119:39978,63120:39979,63121:39980,63122:39981,63123:39982,63124:39983,63125:39984,63126:39985,63127:39986,63128:39987,63129:39988,63130:39989,63131:39990,63132:39991,63133:39992,63134:39993,63135:39994,63136:39995,63137:35301,63138:35307,63139:35311,63140:35390,63141:35622,63142:38739,63143:38633,63144:38643,63145:38639,63146:38662,63147:38657,63148:38664,63149:38671,63150:38670,63151:38698,63152:38701,63153:38704,63154:38718,63155:40832,63156:40835,63157:40837,63158:40838,63159:40839,63160:40840,63161:40841,63162:40842,63163:40844,63164:40702,63165:40715,63166:40717,63167:38585,63168:38588,63169:38589,63170:38606,63171:38610,63172:30655,63173:38624,63174:37518,63175:37550,63176:37576,63177:37694,63178:37738,63179:37834,63180:37775,63181:37950,63182:37995,63183:40063,63184:40066,63185:40069,63186:40070,63187:40071,63188:40072,63189:31267,63190:40075,63191:40078,63192:40080,63193:40081,63194:40082,63195:40084,63196:40085,63197:40090,63198:40091,63199:40094,63200:40095,63201:40096,63202:40097,63203:40098,63204:40099,63205:40101,63206:40102,63207:40103,63208:40104,63209:40105,63210:40107,63211:40109,63212:40110,63213:40112,63214:40113,63215:40114,63216:40115,63217:40116,63218:40117,63219:40118,63220:40119,63221:40122,63222:40123,63223:40124,63224:40125,63225:40132,63226:40133,63227:40134,63228:40135,63229:40138,63230:40139,63296:39996,63297:39997,63298:39998,63299:39999,63300:40000,63301:40001,63302:40002,63303:40003,63304:40004,63305:40005,63306:40006,63307:40007,63308:40008,63309:40009,63310:40010,63311:40011,63312:40012,63313:40013,63314:40014,63315:40015,63316:40016,63317:40017,63318:40018,63319:40019,63320:40020,63321:40021,63322:40022,63323:40023,63324:40024,63325:40025,63326:40026,63327:40027,63328:40028,63329:40029,63330:40030,63331:40031,63332:40032,63333:40033,63334:40034,63335:40035,63336:40036,63337:40037,63338:40038,63339:40039,63340:40040,63341:40041,63342:40042,63343:40043,63344:40044,63345:40045,63346:40046,63347:40047,63348:40048,63349:40049,63350:40050,63351:40051,63352:40052,63353:40053,63354:40054,63355:40055,63356:40056,63357:40057,63358:40058,63360:40059,63361:40061,63362:40062,63363:40064,63364:40067,63365:40068,63366:40073,63367:40074,63368:40076,63369:40079,63370:40083,63371:40086,63372:40087,63373:40088,63374:40089,63375:40093,63376:40106,63377:40108,63378:40111,63379:40121,63380:40126,63381:40127,63382:40128,63383:40129,63384:40130,63385:40136,63386:40137,63387:40145,63388:40146,63389:40154,63390:40155,63391:40160,63392:40161,63393:40140,63394:40141,63395:40142,63396:40143,63397:40144,63398:40147,63399:40148,63400:40149,63401:40151,63402:40152,63403:40153,63404:40156,63405:40157,63406:40159,63407:40162,63408:38780,63409:38789,63410:38801,63411:38802,63412:38804,63413:38831,63414:38827,63415:38819,63416:38834,63417:38836,63418:39601,63419:39600,63420:39607,63421:40536,63422:39606,63423:39610,63424:39612,63425:39617,63426:39616,63427:39621,63428:39618,63429:39627,63430:39628,63431:39633,63432:39749,63433:39747,63434:39751,63435:39753,63436:39752,63437:39757,63438:39761,63439:39144,63440:39181,63441:39214,63442:39253,63443:39252,63444:39647,63445:39649,63446:39654,63447:39663,63448:39659,63449:39675,63450:39661,63451:39673,63452:39688,63453:39695,63454:39699,63455:39711,63456:39715,63457:40637,63458:40638,63459:32315,63460:40578,63461:40583,63462:40584,63463:40587,63464:40594,63465:37846,63466:40605,63467:40607,63468:40667,63469:40668,63470:40669,63471:40672,63472:40671,63473:40674,63474:40681,63475:40679,63476:40677,63477:40682,63478:40687,63479:40738,63480:40748,63481:40751,63482:40761,63483:40759,63484:40765,63485:40766,63486:40772,63552:40163,63553:40164,63554:40165,63555:40166,63556:40167,63557:40168,63558:40169,63559:40170,63560:40171,63561:40172,63562:40173,63563:40174,63564:40175,63565:40176,63566:40177,63567:40178,63568:40179,63569:40180,63570:40181,63571:40182,63572:40183,63573:40184,63574:40185,63575:40186,63576:40187,63577:40188,63578:40189,63579:40190,63580:40191,63581:40192,63582:40193,63583:40194,63584:40195,63585:40196,63586:40197,63587:40198,63588:40199,63589:40200,63590:40201,63591:40202,63592:40203,63593:40204,63594:40205,63595:40206,63596:40207,63597:40208,63598:40209,63599:40210,63600:40211,63601:40212,63602:40213,63603:40214,63604:40215,63605:40216,63606:40217,63607:40218,63608:40219,63609:40220,63610:40221,63611:40222,63612:40223,63613:40224,63614:40225,63616:40226,63617:40227,63618:40228,63619:40229,63620:40230,63621:40231,63622:40232,63623:40233,63624:40234,63625:40235,63626:40236,63627:40237,63628:40238,63629:40239,63630:40240,63631:40241,63632:40242,63633:40243,63634:40244,63635:40245,63636:40246,63637:40247,63638:40248,63639:40249,63640:40250,63641:40251,63642:40252,63643:40253,63644:40254,63645:40255,63646:40256,63647:40257,63648:40258,63649:57908,63650:57909,63651:57910,63652:57911,63653:57912,63654:57913,63655:57914,63656:57915,63657:57916,63658:57917,63659:57918,63660:57919,63661:57920,63662:57921,63663:57922,63664:57923,63665:57924,63666:57925,63667:57926,63668:57927,63669:57928,63670:57929,63671:57930,63672:57931,63673:57932,63674:57933,63675:57934,63676:57935,63677:57936,63678:57937,63679:57938,63680:57939,63681:57940,63682:57941,63683:57942,63684:57943,63685:57944,63686:57945,63687:57946,63688:57947,63689:57948,63690:57949,63691:57950,63692:57951,63693:57952,63694:57953,63695:57954,63696:57955,63697:57956,63698:57957,63699:57958,63700:57959,63701:57960,63702:57961,63703:57962,63704:57963,63705:57964,63706:57965,63707:57966,63708:57967,63709:57968,63710:57969,63711:57970,63712:57971,63713:57972,63714:57973,63715:57974,63716:57975,63717:57976,63718:57977,63719:57978,63720:57979,63721:57980,63722:57981,63723:57982,63724:57983,63725:57984,63726:57985,63727:57986,63728:57987,63729:57988,63730:57989,63731:57990,63732:57991,63733:57992,63734:57993,63735:57994,63736:57995,63737:57996,63738:57997,63739:57998,63740:57999,63741:58000,63742:58001,63808:40259,63809:40260,63810:40261,63811:40262,63812:40263,63813:40264,63814:40265,63815:40266,63816:40267,63817:40268,63818:40269,63819:40270,63820:40271,63821:40272,63822:40273,63823:40274,63824:40275,63825:40276,63826:40277,63827:40278,63828:40279,63829:40280,63830:40281,63831:40282,63832:40283,63833:40284,63834:40285,63835:40286,63836:40287,63837:40288,63838:40289,63839:40290,63840:40291,63841:40292,63842:40293,63843:40294,63844:40295,63845:40296,63846:40297,63847:40298,63848:40299,63849:40300,63850:40301,63851:40302,63852:40303,63853:40304,63854:40305,63855:40306,63856:40307,63857:40308,63858:40309,63859:40310,63860:40311,63861:40312,63862:40313,63863:40314,63864:40315,63865:40316,63866:40317,63867:40318,63868:40319,63869:40320,63870:40321,63872:40322,63873:40323,63874:40324,63875:40325,63876:40326,63877:40327,63878:40328,63879:40329,63880:40330,63881:40331,63882:40332,63883:40333,63884:40334,63885:40335,63886:40336,63887:40337,63888:40338,63889:40339,63890:40340,63891:40341,63892:40342,63893:40343,63894:40344,63895:40345,63896:40346,63897:40347,63898:40348,63899:40349,63900:40350,63901:40351,63902:40352,63903:40353,63904:40354,63905:58002,63906:58003,63907:58004,63908:58005,63909:58006,63910:58007,63911:58008,63912:58009,63913:58010,63914:58011,63915:58012,63916:58013,63917:58014,63918:58015,63919:58016,63920:58017,63921:58018,63922:58019,63923:58020,63924:58021,63925:58022,63926:58023,63927:58024,63928:58025,63929:58026,63930:58027,63931:58028,63932:58029,63933:58030,63934:58031,63935:58032,63936:58033,63937:58034,63938:58035,63939:58036,63940:58037,63941:58038,63942:58039,63943:58040,63944:58041,63945:58042,63946:58043,63947:58044,63948:58045,63949:58046,63950:58047,63951:58048,63952:58049,63953:58050,63954:58051,63955:58052,63956:58053,63957:58054,63958:58055,63959:58056,63960:58057,63961:58058,63962:58059,63963:58060,63964:58061,63965:58062,63966:58063,63967:58064,63968:58065,63969:58066,63970:58067,63971:58068,63972:58069,63973:58070,63974:58071,63975:58072,63976:58073,63977:58074,63978:58075,63979:58076,63980:58077,63981:58078,63982:58079,63983:58080,63984:58081,63985:58082,63986:58083,63987:58084,63988:58085,63989:58086,63990:58087,63991:58088,63992:58089,63993:58090,63994:58091,63995:58092,63996:58093,63997:58094,63998:58095,64064:40355,64065:40356,64066:40357,64067:40358,64068:40359,64069:40360,64070:40361,64071:40362,64072:40363,64073:40364,64074:40365,64075:40366,64076:40367,64077:40368,64078:40369,64079:40370,64080:40371,64081:40372,64082:40373,64083:40374,64084:40375,64085:40376,64086:40377,64087:40378,64088:40379,64089:40380,64090:40381,64091:40382,64092:40383,64093:40384,64094:40385,64095:40386,64096:40387,64097:40388,64098:40389,64099:40390,64100:40391,64101:40392,64102:40393,64103:40394,64104:40395,64105:40396,64106:40397,64107:40398,64108:40399,64109:40400,64110:40401,64111:40402,64112:40403,64113:40404,64114:40405,64115:40406,64116:40407,64117:40408,64118:40409,64119:40410,64120:40411,64121:40412,64122:40413,64123:40414,64124:40415,64125:40416,64126:40417,64128:40418,64129:40419,64130:40420,64131:40421,64132:40422,64133:40423,64134:40424,64135:40425,64136:40426,64137:40427,64138:40428,64139:40429,64140:40430,64141:40431,64142:40432,64143:40433,64144:40434,64145:40435,64146:40436,64147:40437,64148:40438,64149:40439,64150:40440,64151:40441,64152:40442,64153:40443,64154:40444,64155:40445,64156:40446,64157:40447,64158:40448,64159:40449,64160:40450,64161:58096,64162:58097,64163:58098,64164:58099,64165:58100,64166:58101,64167:58102,64168:58103,64169:58104,64170:58105,64171:58106,64172:58107,64173:58108,64174:58109,64175:58110,64176:58111,64177:58112,64178:58113,64179:58114,64180:58115,64181:58116,64182:58117,64183:58118,64184:58119,64185:58120,64186:58121,64187:58122,64188:58123,64189:58124,64190:58125,64191:58126,64192:58127,64193:58128,64194:58129,64195:58130,64196:58131,64197:58132,64198:58133,64199:58134,64200:58135,64201:58136,64202:58137,64203:58138,64204:58139,64205:58140,64206:58141,64207:58142,64208:58143,64209:58144,64210:58145,64211:58146,64212:58147,64213:58148,64214:58149,64215:58150,64216:58151,64217:58152,64218:58153,64219:58154,64220:58155,64221:58156,64222:58157,64223:58158,64224:58159,64225:58160,64226:58161,64227:58162,64228:58163,64229:58164,64230:58165,64231:58166,64232:58167,64233:58168,64234:58169,64235:58170,64236:58171,64237:58172,64238:58173,64239:58174,64240:58175,64241:58176,64242:58177,64243:58178,64244:58179,64245:58180,64246:58181,64247:58182,64248:58183,64249:58184,64250:58185,64251:58186,64252:58187,64253:58188,64254:58189,64320:40451,64321:40452,64322:40453,64323:40454,64324:40455,64325:40456,64326:40457,64327:40458,64328:40459,64329:40460,64330:40461,64331:40462,64332:40463,64333:40464,64334:40465,64335:40466,64336:40467,64337:40468,64338:40469,64339:40470,64340:40471,64341:40472,64342:40473,64343:40474,64344:40475,64345:40476,64346:40477,64347:40478,64348:40484,64349:40487,64350:40494,64351:40496,64352:40500,64353:40507,64354:40508,64355:40512,64356:40525,64357:40528,64358:40530,64359:40531,64360:40532,64361:40534,64362:40537,64363:40541,64364:40543,64365:40544,64366:40545,64367:40546,64368:40549,64369:40558,64370:40559,64371:40562,64372:40564,64373:40565,64374:40566,64375:40567,64376:40568,64377:40569,64378:40570,64379:40571,64380:40572,64381:40573,64382:40576,64384:40577,64385:40579,64386:40580,64387:40581,64388:40582,64389:40585,64390:40586,64391:40588,64392:40589,64393:40590,64394:40591,64395:40592,64396:40593,64397:40596,64398:40597,64399:40598,64400:40599,64401:40600,64402:40601,64403:40602,64404:40603,64405:40604,64406:40606,64407:40608,64408:40609,64409:40610,64410:40611,64411:40612,64412:40613,64413:40615,64414:40616,64415:40617,64416:40618,64417:58190,64418:58191,64419:58192,64420:58193,64421:58194,64422:58195,64423:58196,64424:58197,64425:58198,64426:58199,64427:58200,64428:58201,64429:58202,64430:58203,64431:58204,64432:58205,64433:58206,64434:58207,64435:58208,64436:58209,64437:58210,64438:58211,64439:58212,64440:58213,64441:58214,64442:58215,64443:58216,64444:58217,64445:58218,64446:58219,64447:58220,64448:58221,64449:58222,64450:58223,64451:58224,64452:58225,64453:58226,64454:58227,64455:58228,64456:58229,64457:58230,64458:58231,64459:58232,64460:58233,64461:58234,64462:58235,64463:58236,64464:58237,64465:58238,64466:58239,64467:58240,64468:58241,64469:58242,64470:58243,64471:58244,64472:58245,64473:58246,64474:58247,64475:58248,64476:58249,64477:58250,64478:58251,64479:58252,64480:58253,64481:58254,64482:58255,64483:58256,64484:58257,64485:58258,64486:58259,64487:58260,64488:58261,64489:58262,64490:58263,64491:58264,64492:58265,64493:58266,64494:58267,64495:58268,64496:58269,64497:58270,64498:58271,64499:58272,64500:58273,64501:58274,64502:58275,64503:58276,64504:58277,64505:58278,64506:58279,64507:58280,64508:58281,64509:58282,64510:58283,64576:40619,64577:40620,64578:40621,64579:40622,64580:40623,64581:40624,64582:40625,64583:40626,64584:40627,64585:40629,64586:40630,64587:40631,64588:40633,64589:40634,64590:40636,64591:40639,64592:40640,64593:40641,64594:40642,64595:40643,64596:40645,64597:40646,64598:40647,64599:40648,64600:40650,64601:40651,64602:40652,64603:40656,64604:40658,64605:40659,64606:40661,64607:40662,64608:40663,64609:40665,64610:40666,64611:40670,64612:40673,64613:40675,64614:40676,64615:40678,64616:40680,64617:40683,64618:40684,64619:40685,64620:40686,64621:40688,64622:40689,64623:40690,64624:40691,64625:40692,64626:40693,64627:40694,64628:40695,64629:40696,64630:40698,64631:40701,64632:40703,64633:40704,64634:40705,64635:40706,64636:40707,64637:40708,64638:40709,64640:40710,64641:40711,64642:40712,64643:40713,64644:40714,64645:40716,64646:40719,64647:40721,64648:40722,64649:40724,64650:40725,64651:40726,64652:40728,64653:40730,64654:40731,64655:40732,64656:40733,64657:40734,64658:40735,64659:40737,64660:40739,64661:40740,64662:40741,64663:40742,64664:40743,64665:40744,64666:40745,64667:40746,64668:40747,64669:40749,64670:40750,64671:40752,64672:40753,64673:58284,64674:58285,64675:58286,64676:58287,64677:58288,64678:58289,64679:58290,64680:58291,64681:58292,64682:58293,64683:58294,64684:58295,64685:58296,64686:58297,64687:58298,64688:58299,64689:58300,64690:58301,64691:58302,64692:58303,64693:58304,64694:58305,64695:58306,64696:58307,64697:58308,64698:58309,64699:58310,64700:58311,64701:58312,64702:58313,64703:58314,64704:58315,64705:58316,64706:58317,64707:58318,64708:58319,64709:58320,64710:58321,64711:58322,64712:58323,64713:58324,64714:58325,64715:58326,64716:58327,64717:58328,64718:58329,64719:58330,64720:58331,64721:58332,64722:58333,64723:58334,64724:58335,64725:58336,64726:58337,64727:58338,64728:58339,64729:58340,64730:58341,64731:58342,64732:58343,64733:58344,64734:58345,64735:58346,64736:58347,64737:58348,64738:58349,64739:58350,64740:58351,64741:58352,64742:58353,64743:58354,64744:58355,64745:58356,64746:58357,64747:58358,64748:58359,64749:58360,64750:58361,64751:58362,64752:58363,64753:58364,64754:58365,64755:58366,64756:58367,64757:58368,64758:58369,64759:58370,64760:58371,64761:58372,64762:58373,64763:58374,64764:58375,64765:58376,64766:58377,64832:40754,64833:40755,64834:40756,64835:40757,64836:40758,64837:40760,64838:40762,64839:40764,64840:40767,64841:40768,64842:40769,64843:40770,64844:40771,64845:40773,64846:40774,64847:40775,64848:40776,64849:40777,64850:40778,64851:40779,64852:40780,64853:40781,64854:40782,64855:40783,64856:40786,64857:40787,64858:40788,64859:40789,64860:40790,64861:40791,64862:40792,64863:40793,64864:40794,64865:40795,64866:40796,64867:40797,64868:40798,64869:40799,64870:40800,64871:40801,64872:40802,64873:40803,64874:40804,64875:40805,64876:40806,64877:40807,64878:40808,64879:40809,64880:40810,64881:40811,64882:40812,64883:40813,64884:40814,64885:40815,64886:40816,64887:40817,64888:40818,64889:40819,64890:40820,64891:40821,64892:40822,64893:40823,64894:40824,64896:40825,64897:40826,64898:40827,64899:40828,64900:40829,64901:40830,64902:40833,64903:40834,64904:40845,64905:40846,64906:40847,64907:40848,64908:40849,64909:40850,64910:40851,64911:40852,64912:40853,64913:40854,64914:40855,64915:40856,64916:40860,64917:40861,64918:40862,64919:40865,64920:40866,64921:40867,64922:40868,64923:40869,64924:63788,64925:63865,64926:63893,64927:63975,64928:63985,64929:58378,64930:58379,64931:58380,64932:58381,64933:58382,64934:58383,64935:58384,64936:58385,64937:58386,64938:58387,64939:58388,64940:58389,64941:58390,64942:58391,64943:58392,64944:58393,64945:58394,64946:58395,64947:58396,64948:58397,64949:58398,64950:58399,64951:58400,64952:58401,64953:58402,64954:58403,64955:58404,64956:58405,64957:58406,64958:58407,64959:58408,64960:58409,64961:58410,64962:58411,64963:58412,64964:58413,64965:58414,64966:58415,64967:58416,64968:58417,64969:58418,64970:58419,64971:58420,64972:58421,64973:58422,64974:58423,64975:58424,64976:58425,64977:58426,64978:58427,64979:58428,64980:58429,64981:58430,64982:58431,64983:58432,64984:58433,64985:58434,64986:58435,64987:58436,64988:58437,64989:58438,64990:58439,64991:58440,64992:58441,64993:58442,64994:58443,64995:58444,64996:58445,64997:58446,64998:58447,64999:58448,65000:58449,65001:58450,65002:58451,65003:58452,65004:58453,65005:58454,65006:58455,65007:58456,65008:58457,65009:58458,65010:58459,65011:58460,65012:58461,65013:58462,65014:58463,65015:58464,65016:58465,65017:58466,65018:58467,65019:58468,65020:58469,65021:58470,65022:58471,65088:64012,65089:64013,65090:64014,65091:64015,65092:64017,65093:64019,65094:64020,65095:64024,65096:64031,65097:64032,65098:64033,65099:64035,65100:64036,65101:64039,65102:64040,65103:64041,65104:11905,65105:59414,65106:59415,65107:59416,65108:11908,65109:13427,65110:13383,65111:11912,65112:11915,65113:59422,65114:13726,65115:13850,65116:13838,65117:11916,65118:11927,65119:14702,65120:14616,65121:59430,65122:14799,65123:14815,65124:14963,65125:14800,65126:59435,65127:59436,65128:15182,65129:15470,65130:15584,65131:11943,65132:59441,65133:59442,65134:11946,65135:16470,65136:16735,65137:11950,65138:17207,65139:11955,65140:11958,65141:11959,65142:59451,65143:17329,65144:17324,65145:11963,65146:17373,65147:17622,65148:18017,65149:17996,65150:59459,65152:18211,65153:18217,65154:18300,65155:18317,65156:11978,65157:18759,65158:18810,65159:18813,65160:18818,65161:18819,65162:18821,65163:18822,65164:18847,65165:18843,65166:18871,65167:18870,65168:59476,65169:59477,65170:19619,65171:19615,65172:19616,65173:19617,65174:19575,65175:19618,65176:19731,65177:19732,65178:19733,65179:19734,65180:19735,65181:19736,65182:19737,65183:19886,65184:59492,65185:58472,65186:58473,65187:58474,65188:58475,65189:58476,65190:58477,65191:58478,65192:58479,65193:58480,65194:58481,65195:58482,65196:58483,65197:58484,65198:58485,65199:58486,65200:58487,65201:58488,65202:58489,65203:58490,65204:58491,65205:58492,65206:58493,65207:58494,65208:58495,65209:58496,65210:58497,65211:58498,65212:58499,65213:58500,65214:58501,65215:58502,65216:58503,65217:58504,65218:58505,65219:58506,65220:58507,65221:58508,65222:58509,65223:58510,65224:58511,65225:58512,65226:58513,65227:58514,65228:58515,65229:58516,65230:58517,65231:58518,65232:58519,65233:58520,65234:58521,65235:58522,65236:58523,65237:58524,65238:58525,65239:58526,65240:58527,65241:58528,65242:58529,65243:58530,65244:58531,65245:58532,65246:58533,65247:58534,65248:58535,65249:58536,65250:58537,65251:58538,65252:58539,65253:58540,65254:58541,65255:58542,65256:58543,65257:58544,65258:58545,65259:58546,65260:58547,65261:58548,65262:58549,65263:58550,65264:58551,65265:58552,65266:58553,65267:58554,65268:58555,65269:58556,65270:58557,65271:58558,65272:58559,65273:58560,65274:58561,65275:58562,65276:58563,65277:58564,65278:58565} \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-big5-table.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-big5-table.js deleted file mode 100644 index 909e433a..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-big5-table.js +++ /dev/null @@ -1,25 +0,0 @@ -var http = require('http'); -var fs = require('fs'); -// BIG5 -var cp950_b2u = {host:'moztw.org',path:'/docs/big5/table/cp950-b2u.txt'}, - cp950_u2b = {host:'moztw.org',path:'/docs/big5/table/cp950-u2b.txt'}, - cp950_moz18_b2u = {host:'moztw.org',path:'/docs/big5/table/moz18-b2u.txt'}; - -http.get(cp950_moz18_b2u, function(res) { - var data = ''; - res.on('data', function(chunk) { - data += chunk; - }); - res.on('end', function() { - var table = {}; - data = data.split('\n').slice(1); - data.forEach(function(line, idx) { - var pair = line.split(' '); - var key = parseInt(pair[0]); - var val = parseInt(pair[1]); - table[key] = val; - }); - fs.createWriteSync('encodings/table/big5.js', - 'module.exports = ' + JSON.stringify(table) + ';'); - }); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-singlebyte.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-singlebyte.js deleted file mode 100644 index 2cbebece..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/generation/generate-singlebyte.js +++ /dev/null @@ -1,142 +0,0 @@ -var fs = require("fs"); -var Iconv = require("iconv").Iconv; - - -var encodingFamilies = [ - { - // Windows code pages - encodings: [1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258], - convert: function(cp) { - return { - name: "windows-"+cp, - aliases: ["win"+cp, "cp"+cp, ""+cp], - } - } - }, - { - // ISO-8859 code pages - encodings: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16], - convert: function(i) { - return { - name: "iso-8859-"+i, - aliases: ["cp"+(28590+i), (28590+i)], - } - } - }, - { - // IBM/DOS code pages - encodings: [437, 737, 775, 850, 852, 855, 857, 858, 860, 861, 862, 863, 864, 865, 866, 869], - convert: function(cp) { - return { - name: "CP"+cp, - aliases: ["ibm"+cp, ""+cp], - } - } - }, - { - // Macintosh code pages - encodings: ["macCroatian", "macCyrillic", "macGreek", - "macIceland", "macRoman", "macRomania", - "macThai", "macTurkish", "macUkraine"], - }, - { - // KOI8 code pages - encodings: ["KOI8-R", "KOI8-U"], - }, -]; - - -var encodings = { - // Aliases. - "ascii8bit": "ascii", - "usascii": "ascii", - - "latin1": "iso88591", - "latin2": "iso88592", - "latin3": "iso88593", - "latin4": "iso88594", - "latin6": "iso885910", - "latin7": "iso885913", - "latin8": "iso885914", - "latin9": "iso885915", - "latin10": "iso885916", - - "cp819": "iso88951", - "arabic": "iso88596", - "arabic8": "iso88596", - "greek" : "iso88597", - "greek8" : "iso88597", - "hebrew": "iso88598", - "hebrew8": "iso88598", - "turkish": "iso88599", - "turkish8": "iso88599", - "thai": "iso885911", - "thai8": "iso885911", - "tis620": "iso885911", - "windows874": "iso885911", - "win874": "iso885911", - "cp874": "iso885911", - "874": "iso885911", - "celtic": "iso885914", - "celtic8": "iso885914", - - "cp20866": "koi8r", - "20866": "koi8r", - "ibm878": "koi8r", - "cp21866": "koi8u", - "21866": "koi8u", - "ibm1168": "koi8u", - -}; - -// Add all encodings from encodingFamilies. -encodingFamilies.forEach(function(family){ - family.encodings.forEach(function(encoding){ - if (family.convert) - encoding = family.convert(encoding); - - var encodingIconvName = encoding.name ? encoding.name : encoding; - var encodingName = encodingIconvName.replace(/[-_]/g, "").toLowerCase(); - - encodings[encodingName] = { - type: "singlebyte", - chars: generateCharsString(encodingIconvName) - }; - - if (encoding.aliases) - encoding.aliases.forEach(function(alias){ - encodings[alias] = encodingName; - }); - }); -}); - -// Write encodings. -fs.writeFileSync("encodings/singlebyte.js", - "module.exports = " + JSON.stringify(encodings, undefined, " ") + ";"); - - -function generateCharsString(encoding) { - console.log("Generate encoding for " + encoding); - var iconvToUtf8 = new Iconv(encoding, "UTF-8"); - var chars = ""; - - for (var b = 0x80; b < 0x100; b++) { - - try { - var convertedChar = iconvToUtf8.convert(new Buffer([b])).toString(); - - if (convertedChar.length != 1) - throw new Error("Single-byte encoding error: Must return single char."); - } catch (exception) { - if (exception.code === "EILSEQ") { - convertedChar = "\ufffd"; - } else { - throw exception; - } - } - - chars += convertedChar; - } - - return chars; -} diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/index.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/index.js deleted file mode 100644 index a55691b1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/index.js +++ /dev/null @@ -1,231 +0,0 @@ -var RE_SPACEDASH = /[- ]/g; -// Module exports -var iconv = module.exports = { - toEncoding: function(str, encoding) { - return iconv.getCodec(encoding).toEncoding(str); - }, - fromEncoding: function(buf, encoding) { - return iconv.getCodec(encoding).fromEncoding(buf); - }, - encodingExists: function(enc) { - loadEncodings(); - enc = enc.replace(RE_SPACEDASH, "").toLowerCase(); - return (iconv.encodings[enc] !== undefined); - }, - - defaultCharUnicode: '�', - defaultCharSingleByte: '?', - - encodingsLoaded: false, - - // Get correct codec for given encoding. - getCodec: function(encoding) { - loadEncodings(); - var enc = encoding || "utf8"; - var codecOptions = undefined; - while (1) { - if (getType(enc) === "String") - enc = enc.replace(RE_SPACEDASH, "").toLowerCase(); - var codec = iconv.encodings[enc]; - var type = getType(codec); - if (type === "String") { - // Link to other encoding. - codecOptions = {originalEncoding: enc}; - enc = codec; - } - else if (type === "Object" && codec.type != undefined) { - // Options for other encoding. - codecOptions = codec; - enc = codec.type; - } - else if (type === "Function") - // Codec itself. - return codec(codecOptions); - else - throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); - } - }, - - // Define basic encodings - encodings: { - internal: function(options) { - return { - toEncoding: toInternalEncoding, - fromEncoding: fromInternalEncoding, - options: options - }; - }, - utf8: "internal", - ucs2: "internal", - binary: "internal", - ascii: "internal", - base64: "internal", - - // Codepage single-byte encodings. - singlebyte: function(options) { - // Prepare chars if needed - if (!options.charsBuf) { - if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256)) - throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)"); - - if (options.chars.length === 128) - options.chars = asciiString + options.chars; - - options.charsBuf = new Buffer(options.chars, 'ucs2'); - } - - if (!options.revCharsBuf) { - options.revCharsBuf = new Buffer(65536); - var defChar = iconv.defaultCharSingleByte.charCodeAt(0); - for (var i = 0; i < options.revCharsBuf.length; i++) - options.revCharsBuf[i] = defChar; - for (var i = 0; i < options.chars.length; i++) - options.revCharsBuf[options.chars.charCodeAt(i)] = i; - } - - return { - toEncoding: toSingleByteEncoding, - fromEncoding: fromSingleByteEncoding, - options: options, - }; - }, - - // Codepage double-byte encodings. - table: function(options) { - if (!options.table) { - throw new Error("Encoding '" + options.type + "' has incorect 'table' option"); - } - if (!options.revCharsTable) { - var revCharsTable = options.revCharsTable = {}; - for (var i = 0; i <= 0xFFFF; i++) { - revCharsTable[i] = 0; - } - - var table = options.table; - for (var key in table) { - revCharsTable[table[key]] = +key; - } - } - - return { - toEncoding: toTableEncoding, - fromEncoding: fromTableEncoding, - options: options, - }; - } - } -}; - -function toInternalEncoding(str) { - return new Buffer(ensureString(str), this.options.originalEncoding); -} - -function fromInternalEncoding(buf) { - return ensureBuffer(buf).toString(this.options.originalEncoding); -} - -function toTableEncoding(str) { - str = ensureString(str); - var strLen = str.length; - var revCharsTable = this.options.revCharsTable; - var newBuf = new Buffer(strLen*2), gbkcode, unicode, - defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)]; - - for (var i = 0, j = 0; i < strLen; i++) { - unicode = str.charCodeAt(i); - if (unicode >> 7) { - gbkcode = revCharsTable[unicode] || defaultChar; - newBuf[j++] = gbkcode >> 8; //high byte; - newBuf[j++] = gbkcode & 0xFF; //low byte - } else {//ascii - newBuf[j++] = unicode; - } - } - return newBuf.slice(0, j); -} - -function fromTableEncoding(buf) { - buf = ensureBuffer(buf); - var bufLen = buf.length; - var table = this.options.table; - var newBuf = new Buffer(bufLen*2), unicode, gbkcode, - defaultChar = iconv.defaultCharUnicode.charCodeAt(0); - - for (var i = 0, j = 0; i < bufLen; i++, j+=2) { - gbkcode = buf[i]; - if (gbkcode & 0x80) { - gbkcode = (gbkcode << 8) + buf[++i]; - unicode = table[gbkcode] || defaultChar; - } else { - unicode = gbkcode; - } - newBuf[j] = unicode & 0xFF; //low byte - newBuf[j+1] = unicode >> 8; //high byte - } - return newBuf.slice(0, j).toString('ucs2'); -} - -function toSingleByteEncoding(str) { - str = ensureString(str); - - var buf = new Buffer(str.length); - var revCharsBuf = this.options.revCharsBuf; - for (var i = 0; i < str.length; i++) - buf[i] = revCharsBuf[str.charCodeAt(i)]; - - return buf; -} - -function fromSingleByteEncoding(buf) { - buf = ensureBuffer(buf); - - // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. - var charsBuf = this.options.charsBuf; - var newBuf = new Buffer(buf.length*2); - var idx1 = 0, idx2 = 0; - for (var i = 0, _len = buf.length; i < _len; i++) { - idx1 = buf[i]*2; idx2 = i*2; - newBuf[idx2] = charsBuf[idx1]; - newBuf[idx2+1] = charsBuf[idx1+1]; - } - return newBuf.toString('ucs2'); -} - -// Add aliases to convert functions -iconv.encode = iconv.toEncoding; -iconv.decode = iconv.fromEncoding; - -// Load other encodings manually from files in /encodings dir. -function loadEncodings() { - if (!iconv.encodingsLoaded) { - [ require('./encodings/singlebyte'), - require('./encodings/gbk'), - require('./encodings/big5') - ].forEach(function(encodings) { - for (var key in encodings) - iconv.encodings[key] = encodings[key] - }); - iconv.encodingsLoaded = true; - } -} - - - -// Utilities -var asciiString = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; - -var ensureBuffer = function(buf) { - buf = buf || new Buffer(0); - return (buf instanceof Buffer) ? buf : new Buffer(""+buf, "binary"); -} - -var ensureString = function(str) { - str = str || ""; - return (str instanceof Buffer) ? str.toString('utf8') : (""+str); -} - -var getType = function(obj) { - return Object.prototype.toString.call(obj).slice(8, -1); -} - diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/package.json b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/package.json deleted file mode 100644 index a9be16be..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/package.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "name": "iconv-lite", - "description": "Convert character encodings in pure javascript.", - "version": "0.2.11", - "license": "MIT", - "keywords": [ - "iconv", - "convert", - "charset" - ], - "author": { - "name": "Alexander Shtuchkin", - "email": "ashtuchkin@gmail.com" - }, - "contributors": [ - { - "name": "Jinwu Zhan", - "url": "https://github.com/jenkinv" - }, - { - "name": "Adamansky Anton", - "url": "https://github.com/adamansky" - }, - { - "name": "George Stagas", - "url": "https://github.com/stagas" - }, - { - "name": "Mike D Pilsbury", - "url": "https://github.com/pekim" - }, - { - "name": "Niggler", - "url": "https://github.com/Niggler" - }, - { - "name": "wychi", - "url": "https://github.com/wychi" - }, - { - "name": "David Kuo", - "url": "https://github.com/david50407" - }, - { - "name": "ChangZhuo Chen", - "url": "https://github.com/czchen" - }, - { - "name": "Lee Treveil", - "url": "https://github.com/leetreveil" - }, - { - "name": "Brian White", - "url": "https://github.com/mscdex" - } - ], - "main": "index.js", - "homepage": "https://github.com/ashtuchkin/iconv-lite", - "repository": { - "type": "git", - "url": "git://github.com/ashtuchkin/iconv-lite.git" - }, - "engines": { - "node": ">=0.4.0" - }, - "scripts": { - "test": "vows --spec" - }, - "devDependencies": { - "vows": "", - "iconv": ">=1.1" - }, - "bugs": { - "url": "https://github.com/ashtuchkin/iconv-lite/issues" - }, - "_id": "iconv-lite@0.2.11", - "dist": { - "shasum": "1ce60a3a57864a292d1321ff4609ca4bb965adc8", - "tarball": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz" - }, - "_from": "iconv-lite@~0.2.11", - "_npmVersion": "1.3.2", - "_npmUser": { - "name": "ashtuchkin", - "email": "ashtuchkin@gmail.com" - }, - "maintainers": [ - { - "name": "ashtuchkin", - "email": "ashtuchkin@gmail.com" - } - ], - "directories": {}, - "_shasum": "1ce60a3a57864a292d1321ff4609ca4bb965adc8", - "_resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5-test.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5-test.js deleted file mode 100644 index f3fe1a82..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5-test.js +++ /dev/null @@ -1,36 +0,0 @@ -var vows = require('vows'), - fs = require('fs'), - assert = require('assert'), - iconv = require(__dirname + '/../'); - -var testString = "中文abc", //unicode contains Big5-code and ascii - testStringBig5Buffer = new Buffer([0xa4,0xa4,0xa4,0xe5,0x61,0x62,0x63]), - testString2 = '測試', - testStringBig5Buffer2 = new Buffer([0xb4, 0xfa, 0xb8, 0xd5]); - -vows.describe("Big5 tests").addBatch({ - "Big5 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testString, "big5").toString('binary'), testStringBig5Buffer.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer, "big5"), testString); - assert.strictEqual(iconv.toEncoding(testString2, 'big5').toString('binary'), testStringBig5Buffer2.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer2, 'big5'), testString2); - }, - "cp950 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testString, "cp950").toString('binary'), testStringBig5Buffer.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringBig5Buffer, "cp950"), testString); - }, - "Big5 file read decoded,compare with iconv result": function() { - var contentBuffer = fs.readFileSync(__dirname+"/big5File.txt"); - var str = iconv.fromEncoding(contentBuffer, "big5"); - var iconvc = new (require('iconv').Iconv)('big5','utf8'); - assert.strictEqual(iconvc.convert(contentBuffer).toString(), str); - }, - "Big5 correctly decodes and encodes characters · and ×": function() { - // https://github.com/ashtuchkin/iconv-lite/issues/13 - // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT - var chars = "·×"; - var big5Chars = new Buffer([0xA1, 0x50, 0xA1, 0xD1]); - assert.strictEqual(iconv.toEncoding(chars, "big5").toString('binary'), big5Chars.toString('binary')); - assert.strictEqual(iconv.fromEncoding(big5Chars, "big5"), chars) - }, -}).export(module) diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5File.txt b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5File.txt deleted file mode 100644 index 9c13042c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/big5File.txt +++ /dev/null @@ -1,13 +0,0 @@ - - - meta ¼ÐÅÒªº¨Ï¥Î¡G¤¤¤åºô­¶ - - - - -³o¬O¤@­ÓÁcÅ餤¤åºô­¶¡I
        -(This page uses big5 character set.)
        -charset=big5 - - - \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/cyrillic-test.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/cyrillic-test.js deleted file mode 100644 index 259d2832..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/cyrillic-test.js +++ /dev/null @@ -1,86 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var baseStrings = { - empty: "", - hi: "Привет!", - ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f', - rus: "ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑ", - additional1: "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋÐђ‘’“â€â€¢â€“—™љ›њќћџ ЎўЈ¤Ò¦§Ð©Є«¬\xAD®Ї°±Ііґµ¶·ё№є»јЅѕї", - additional2: "─│┌â”└┘├┤┬┴┼▀▄█▌â–░▒▓⌠■∙√≈≤≥ ⌡°²·÷â•║╒ё╓╔╕╖╗╘╙╚╛╜â•╞╟╠╡Ð╢╣╤╥╦╧╨╩╪╫╬©", - additional3: " ÐЂЃЄЅІЇЈЉЊЋЌ­ЎÐ№ёђѓєѕіїјљњћќ§ўџ", - untranslatable: "£Åçþÿ¿", -}; - -var encodings = [{ - name: "Win-1251", - variations: ['win1251', 'Windows-1251', 'windows1251', 'CP1251', 1251], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xcf\xf0\xe8\xe2\xe5\xf2!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - rus: new Buffer('\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'), - additional1: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf','binary'), - } -}, { - name: "Koi8-R", - variations: ['koi8r', 'KOI8-R', 'cp20866', 20866], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xf0\xd2\xc9\xd7\xc5\xd4!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - rus: new Buffer('\xe1\xe2\xf7\xe7\xe4\xe5\xf6\xfa\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf2\xf3\xf4\xf5\xe6\xe8\xe3\xfe\xfb\xfd\xff\xf9\xf8\xfc\xe0\xf1\xc1\xc2\xd7\xc7\xc4\xc5\xd6\xda\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd2\xd3\xd4\xd5\xc6\xc8\xc3\xde\xdb\xdd\xdf\xd9\xd8\xdc\xc0\xd1', 'binary'), - additional2: new Buffer('\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf', 'binary'), - } -}, { - name: "ISO 8859-5", - variations: ['iso88595', 'ISO-8859-5', 'ISO 8859-5', 'cp28595', 28595], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xbf\xe0\xd8\xd2\xd5\xe2!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - rus: new Buffer('\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef', 'binary'), - additional3: new Buffer('\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', 'binary'), - } -}]; - -var testsBatch = {}; -encodings.forEach(function(encoding) { - var enc = encoding.variations[0]; - var key = "hi"; - var tests = { - "Convert to empty buffer": function() { - assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); - }, - "Convert from empty buffer": function() { - assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); - }, - "Convert from buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), - baseStrings[key]); - }, - "Convert to buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), - encoding.encodedStrings[key].toString('binary')); - }, - "Try different variations of encoding": function() { - encoding.variations.forEach(function(enc) { - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]); - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); - }); - }, - "Untranslatable chars are converted to defaultCharSingleByte": function() { - var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); - assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. - } - }; - - testsBatch[encoding.name+":"] = tests; -}); - -vows.describe("Test Cyrillic encodings").addBatch(testsBatch).export(module); - diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbk-test.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbk-test.js deleted file mode 100644 index 7b2e47bd..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbk-test.js +++ /dev/null @@ -1,38 +0,0 @@ -var vows = require('vows'), - fs = require('fs'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var testString = "中国abc",//unicode contains GBK-code and ascii - testStringGBKBuffer = new Buffer([0xd6,0xd0,0xb9,0xfa,0x61,0x62,0x63]); - -vows.describe("GBK tests").addBatch({ - "Vows is working": function() {}, - "Return values are of correct types": function() { - assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer); - var s = iconv.fromEncoding(new Buffer(testString), "utf8"); - assert.strictEqual(Object.prototype.toString.call(s), "[object String]"); - }, - "GBK correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testString, "GBK").toString('binary'), testStringGBKBuffer.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GBK"), testString); - }, - "GB2312 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testString, "GB2312").toString('binary'), testStringGBKBuffer.toString('binary')); - assert.strictEqual(iconv.fromEncoding(testStringGBKBuffer, "GB2312"), testString); - }, - "GBK file read decoded,compare with iconv result": function() { - var contentBuffer = fs.readFileSync(__dirname+"/gbkFile.txt"); - var str = iconv.fromEncoding(contentBuffer, "GBK"); - var iconvc = new (require('iconv').Iconv)('GBK','utf8'); - assert.strictEqual(iconvc.convert(contentBuffer).toString(), str); - }, - "GBK correctly decodes and encodes characters · and ×": function() { - // https://github.com/ashtuchkin/iconv-lite/issues/13 - // Reference: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT - var chars = "·×"; - var gbkChars = new Buffer([0xA1, 0xA4, 0xA1, 0xC1]); - assert.strictEqual(iconv.toEncoding(chars, "GBK").toString('binary'), gbkChars.toString('binary')); - assert.strictEqual(iconv.fromEncoding(gbkChars, "GBK"), chars) - }, -}).export(module) diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbkFile.txt b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbkFile.txt deleted file mode 100644 index 345b5d09..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/gbkFile.txt +++ /dev/null @@ -1,14 +0,0 @@ -°Ù¶Èһϣ¬Äã¾ÍÖªµÀ - - - - - - - - - - - \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/greek-test.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/greek-test.js deleted file mode 100644 index 0394ee6f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/greek-test.js +++ /dev/null @@ -1,79 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var baseStrings = { - empty: "", - hi: "Γειά!", - ascii: '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f', - greek: "αβγδεζηθικλμνξοπÏστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩάέήίόÏώΆΈΉΊΌΎÎϊϋΪΫ", - untranslatable: "Åçþÿ¿" -}; - -var encodings = [{ - name: "windows1253", - variations: ['windows-1253', 'win-1253', 'win1253', 'cp1253', 'cp-1253', 1253], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xa2\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'), - } -}, { - name: "iso88597", - variations: ['iso-8859-7', 'greek', 'greek8', 'cp28597', 'cp-28597', 28597], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\xc3\xe5\xe9\xdc!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - greek: new Buffer('\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xdc\xdd\xde\xdf\xfc\xfd\xfe\xb6\xb8\xb9\xba\xbc\xbe\xbf\xfa\xfb\xda\xdb', 'binary'), - } -}, { - name: "cp737", - variations: ['cp-737', 737], - encodedStrings: { - empty: new Buffer(''), - hi: new Buffer('\x82\x9c\xa0\xe1!', 'binary'), - ascii: new Buffer(baseStrings.ascii, 'binary'), - greek: new Buffer('\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xab\xac\xad\xae\xaf\xe0\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\xe1\xe2\xe3\xe5\xe6\xe7\xe9\xea\xeb\xec\xed\xee\xef\xf0\xe4\xe8\xf4\xf5', 'binary'), - } -}]; - -var testsBatch = {}; -encodings.forEach(function(encoding) { - var enc = encoding.variations[0]; - var key = "hi"; - var tests = { - "Convert to empty buffer": function() { - assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); - }, - "Convert from empty buffer": function() { - assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); - }, - "Convert from buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), - baseStrings[key]); - }, - "Convert to buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), - encoding.encodedStrings[key].toString('binary')); - }, - "Try different variations of encoding": function() { - encoding.variations.forEach(function(enc) { - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), baseStrings[key]); - assert.strictEqual(iconv.toEncoding(baseStrings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); - }); - }, - "Untranslatable chars are converted to defaultCharSingleByte": function() { - var expected = baseStrings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); - assert.strictEqual(iconv.toEncoding(baseStrings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. - } - }; - - testsBatch[encoding.name+":"] = tests; -}); - -vows.describe("Test Greek encodings").addBatch(testsBatch).export(module); diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/main-test.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/main-test.js deleted file mode 100644 index 50177f22..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/main-test.js +++ /dev/null @@ -1,55 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var testString = "Hello123!"; -var testStringLatin1 = "Hello123!£Å÷×çþÿ¿®"; -var testStringBase64 = "SGVsbG8xMjMh"; - -vows.describe("Generic UTF8-UCS2 tests").addBatch({ - "Vows is working": function() {}, - "Return values are of correct types": function() { - assert.ok(iconv.toEncoding(testString, "utf8") instanceof Buffer); - - var s = iconv.fromEncoding(new Buffer(testString), "utf8"); - assert.strictEqual(Object.prototype.toString.call(s), "[object String]"); - }, - "Internal encodings all correctly encoded/decoded": function() { - ['utf8', "UTF-8", "UCS2", "binary", ""].forEach(function(enc) { - assert.strictEqual(iconv.toEncoding(testStringLatin1, enc).toString(enc), testStringLatin1); - assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, enc), enc), testStringLatin1); - }); - }, - "Base64 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testStringBase64, "base64").toString("binary"), testString); - assert.strictEqual(iconv.fromEncoding(new Buffer(testString, "binary"), "base64"), testStringBase64); - }, - "Latin1 correctly encoded/decoded": function() { - assert.strictEqual(iconv.toEncoding(testStringLatin1, "latin1").toString("binary"), testStringLatin1); - assert.strictEqual(iconv.fromEncoding(new Buffer(testStringLatin1, "binary"), "latin1"), testStringLatin1); - }, - "Convert from string, not buffer (binary encoding used)": function() { - assert.strictEqual(iconv.fromEncoding(testStringLatin1, "binary"), testStringLatin1); - }, - "Convert to string, not buffer (utf8 used)": function() { - var res = iconv.toEncoding(new Buffer(testStringLatin1, "utf8")); - assert.ok(res instanceof Buffer); - assert.strictEqual(res.toString("utf8"), testStringLatin1); - }, - "Throws on unknown encodings": function() { - assert.throws(function() { iconv.toEncoding("a", "xxx"); }); - assert.throws(function() { iconv.fromEncoding("a", "xxx"); }); - }, - "Convert non-strings and non-buffers": function() { - assert.strictEqual(iconv.toEncoding({}, "utf8").toString(), "[object Object]"); - assert.strictEqual(iconv.toEncoding(10, "utf8").toString(), "10"); - assert.strictEqual(iconv.toEncoding(undefined, "utf8").toString(), ""); - assert.strictEqual(iconv.fromEncoding({}, "utf8"), "[object Object]"); - assert.strictEqual(iconv.fromEncoding(10, "utf8"), "10"); - assert.strictEqual(iconv.fromEncoding(undefined, "utf8"), ""); - }, - "Aliases encode and decode work the same as toEncoding and fromEncoding": function() { - assert.strictEqual(iconv.toEncoding(testString, "latin1").toString("binary"), iconv.encode(testString, "latin1").toString("binary")); - assert.strictEqual(iconv.fromEncoding(testStringLatin1, "latin1"), iconv.decode(testStringLatin1, "latin1")); - }, -}).export(module) diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/performance.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/performance.js deleted file mode 100644 index 835deac5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/performance.js +++ /dev/null @@ -1,67 +0,0 @@ - -var iconv = require('iconv'); -var iconv_lite = require("../index"); - -var encoding = process.argv[2] || "windows-1251"; -var convertTimes = 10000; - -var encodingStrings = { - 'windows-1251': 'This is a test string 32 chars..', - 'gbk': '这是中文字符测试。。ï¼@ï¿¥%12', - 'utf8': '这是中文字符测试。。ï¼@ï¿¥%12This is a test string 48 chars..', -}; -// Test encoding. -var str = encodingStrings[encoding]; -if (!str) { - throw new Error('Don\'t support ' + encoding + ' performance test.'); -} -for (var i = 0; i < 13; i++) { - str = str + str; -} - -console.log('\n' + encoding + ' charset performance test:'); -console.log("\nEncoding "+str.length+" chars "+convertTimes+" times:"); - -var start = Date.now(); -var converter = new iconv.Iconv("utf8", encoding); -for (var i = 0; i < convertTimes; i++) { - var b = converter.convert(str); -} -var duration = Date.now() - start; -var mbs = convertTimes*b.length/duration/1024; - -console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - -var start = Date.now(); -for (var i = 0; i < convertTimes; i++) { - var b = iconv_lite.encode(str, encoding); -} -var duration = Date.now() - start; -var mbs = convertTimes*b.length/duration/1024; - -console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - - -// Test decoding. -var buf = iconv_lite.encode(str, encoding); -console.log("\nDecoding "+buf.length+" bytes "+convertTimes+" times:"); - -var start = Date.now(); -var converter = new iconv.Iconv(encoding, "utf8"); -for (var i = 0; i < convertTimes; i++) { - var s = converter.convert(buf).toString(); -} -var duration = Date.now() - start; -var mbs = convertTimes*buf.length/duration/1024; - -console.log("iconv: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - -var start = Date.now(); -for (var i = 0; i < convertTimes; i++) { - var s = iconv_lite.decode(buf, encoding); -} -var duration = Date.now() - start; -var mbs = convertTimes*buf.length/duration/1024; - -console.log("iconv-lite: "+duration+"ms, "+mbs.toFixed(2)+" Mb/s."); - diff --git a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/turkish-test.js b/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/turkish-test.js deleted file mode 100644 index b2eb68e6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/iconv-lite/test/turkish-test.js +++ /dev/null @@ -1,90 +0,0 @@ -var vows = require('vows'), - assert = require('assert'), - iconv = require(__dirname+'/../'); - -var ascii = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+ - ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; - -var encodings = [{ - name: "windows1254", - variations: ['windows-1254', 'win-1254', 'win1254', 'cp1254', 'cp-1254', 1254], - strings: { - empty: "", - ascii: ascii, - turkish: "€‚ƒ„…†‡ˆ‰Š‹Œ‘’“â€â€¢â€“—˜™š›œŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", - untranslatable: "\x81\x8d\x8e\x8f\x90\x9d\x9e" - }, - encodedStrings: { - empty: new Buffer(''), - ascii: new Buffer(ascii, 'binary'), - turkish: new Buffer( - '\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c' + - '\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9f' + - '\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf' + - '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' + - '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' + - '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' + - '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' + - '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', - 'binary'), - } -}, { - name: "iso88599", - variations: ['iso-8859-9', 'turkish', 'turkish8', 'cp28599', 'cp-28599', 28599], - strings: { - empty: "", - ascii: ascii, - turkish: "\xa0¡¢£¤¥¦§¨©ª«¬\xad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", - untranslatable: '' - }, - encodedStrings: { - empty: new Buffer(''), - ascii: new Buffer(ascii, 'binary'), - turkish: new Buffer( - '\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf' + - '\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf' + - '\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf' + - '\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf' + - '\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef' + - '\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff', - 'binary') - } -}]; - -var testsBatch = {}; -encodings.forEach(function(encoding) { - var enc = encoding.variations[0]; - var key = "turkish"; - var tests = { - "Convert to empty buffer": function() { - assert.strictEqual(iconv.toEncoding("", enc).toString('binary'), new Buffer('').toString('binary')); - }, - "Convert from empty buffer": function() { - assert.strictEqual(iconv.fromEncoding(new Buffer(''), enc), ""); - }, - "Convert from buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), - encoding.strings[key]); - }, - "Convert to buffer": function() { - for (var key in encoding.encodedStrings) - assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), - encoding.encodedStrings[key].toString('binary')); - }, - "Try different variations of encoding": function() { - encoding.variations.forEach(function(enc) { - assert.strictEqual(iconv.fromEncoding(encoding.encodedStrings[key], enc), encoding.strings[key]); - assert.strictEqual(iconv.toEncoding(encoding.strings[key], enc).toString('binary'), encoding.encodedStrings[key].toString('binary')); - }); - }, - "Untranslatable chars are converted to defaultCharSingleByte": function() { - var expected = encoding.strings.untranslatable.split('').map(function(c) {return iconv.defaultCharSingleByte; }).join(''); - assert.strictEqual(iconv.toEncoding(encoding.strings.untranslatable, enc).toString('binary'), expected); // Only '?' characters. - } - }; - - testsBatch[encoding.name+":"] = tests; -}); - -vows.describe("Test Turkish encodings").addBatch(testsBatch).export(module); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/HISTORY.md b/spec/fixture/node_modules/grunt/node_modules/js-yaml/HISTORY.md deleted file mode 100644 index dfc48c2b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/HISTORY.md +++ /dev/null @@ -1,155 +0,0 @@ -2.0.5 / 2013-04-26 ------------------- - -* Close security issue in !!js/function constructor. - Big thanks to @nealpoole for security audit. - - -2.0.4 / 2013-04-08 ------------------- - -* Updated .npmignore to reduce package size - - -2.0.3 / 2013-02-26 ------------------- - -* Fixed dumping of empty arrays ans objects. ([] and {} instead of null) - - -2.0.2 / 2013-02-15 ------------------- - -* Fixed input validation: tabs are printable characters. - - -2.0.1 / 2013-02-09 ------------------- - -* Fixed error, when options not passed to function cass - - -2.0.0 / 2013-02-09 ------------------- - -* Full rewrite. New architecture. Fast one-stage parsing. -* Changed custom types API. -* Added YAML dumper. - - -1.0.3 / 2012-11-05 ------------------- - -* Fixed utf-8 files loading. - - -1.0.2 / 2012-08-02 ------------------- - -* Pull out hand-written shims. Use ES5-Shims for old browsers support. See #44. -* Fix timstamps incorectly parsed in local time when no time part specified. - - -1.0.1 / 2012-07-07 ------------------- - -* Fixes `TypeError: 'undefined' is not an object` under Safari. Thanks Phuong. -* Fix timestamps incorrectly parsed in local time. Thanks @caolan. Closes #46. - - -1.0.0 / 2012-07-01 ------------------- - -* `y`, `yes`, `n`, `no`, `on`, `off` are not converted to Booleans anymore. - Fixes #42. -* `require(filename)` now returns a single document and throws an Error if - file contains more than one document. -* CLI was merged back from js-yaml.bin - - -0.3.7 / 2012-02-28 ------------------- - -* Fix export of `addConstructor()`. Closes #39. - - -0.3.6 / 2012-02-22 ------------------- - -* Removed AMD parts - too buggy to use. Need help to rewrite from scratch -* Removed YUI compressor warning (renamed `double` variable). Closes #40. - - -0.3.5 / 2012-01-10 ------------------- - -* Workagound for .npmignore fuckup under windows. Thanks to airportyh. - - -0.3.4 / 2011-12-24 ------------------- - -* Fixes str[] for oldIEs support. -* Adds better has change support for browserified demo. -* improves compact output of Error. Closes #33. - - -0.3.3 / 2011-12-20 ------------------- - -* jsyaml executable moved to separate module. -* adds `compact` stringification of Errors. - - -0.3.2 / 2011-12-16 ------------------- - -* Fixes ug with block style scalars. Closes #26. -* All sources are passing JSLint now. -* Fixes bug in Safari. Closes #28. -* Fixes bug in Opers. Closes #29. -* Improves browser support. Closes #20. -* Added jsyaml executable. -* Added !!js/function support. Closes #12. - - -0.3.1 / 2011-11-18 ------------------- - -* Added AMD support for browserified version. -* Wrapped browserified js-yaml into closure. -* Fixed the resolvement of non-specific tags. Closes #17. -* Added permalinks for online demo YAML snippets. Now we have YPaste service, lol. -* Added !!js/regexp and !!js/undefined types. Partially solves #12. -* Fixed !!set mapping. -* Fixed month parse in dates. Closes #19. - - -0.3.0 / 2011-11-09 ------------------- - -* Removed JS.Class dependency. Closes #3. -* Added browserified version. Closes #13. -* Added live demo of browserified version. -* Ported some of the PyYAML tests. See #14. -* Fixed timestamp bug when fraction was given. - - -0.2.2 / 2011-11-06 ------------------- - -* Fixed crash on docs without ---. Closes #8. -* Fixed miltiline string parse -* Fixed tests/comments for using array as key - - -0.2.1 / 2011-11-02 ------------------- - -* Fixed short file read (<4k). Closes #9. - - -0.2.0 / 2011-11-02 ------------------- - -* First public release diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/LICENSE b/spec/fixture/node_modules/grunt/node_modules/js-yaml/LICENSE deleted file mode 100644 index 0f16ee95..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -(The MIT License) - -Copyright (C) 2011, 2013 by Vitaly Puzrin - -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/spec/fixture/node_modules/grunt/node_modules/js-yaml/README.md b/spec/fixture/node_modules/grunt/node_modules/js-yaml/README.md deleted file mode 100644 index e326d602..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/README.md +++ /dev/null @@ -1,249 +0,0 @@ -JS-YAML - YAML 1.2 parser and serializer for JavaScript -======================================================= - -[![Build Status](https://secure.travis-ci.org/nodeca/js-yaml.png)](http://travis-ci.org/nodeca/js-yaml) - -[Online Demo](http://nodeca.github.com/js-yaml/) - - -This is an implementation of [YAML](http://yaml.org/), a human friendly data -serialization language. Started as [PyYAML](http://pyyaml.org/) port, it was -completely rewritten from scratch. Now it's very fast, and supports 1.2 spec. - - -Breaking changes in 1.x.x -> 2.0.x ----------------------------------- - -If your have not used __custom__ tags or loader classes - no changes needed. Just -upgrade library and enjoy high parse speed. - -In other case, you should rewrite your tag constructors and custom loader -classes, to conform new schema-based API. See -[examples](https://github.com/nodeca/js-yaml/tree/master/examples) and -[wiki](https://github.com/nodeca/js-yaml/wiki) for details. -Note, that parser internals were completely rewritten. - - -Installation ------------- - -### YAML module for node.js - -``` -npm install js-yaml -``` - - -### CLI executable - -If you want to inspect your YAML files from CLI, install js-yaml globally: - -``` -npm install js-yaml -g -``` - -#### Usage - -``` -usage: js-yaml [-h] [-v] [-c] [-j] [-t] file - -Positional arguments: - file File with YAML document(s) - -Optional arguments: - -h, --help Show this help message and exit. - -v, --version Show program's version number and exit. - -c, --compact Display errors in compact mode - -j, --to-json Output a non-funky boring JSON - -t, --trace Show stack trace on error -``` - - -### Bundled YAML library for browsers - -``` html - - -``` - -Browser support was done mostly for online demo. If you find any errors - feel -free to send pull requests with fixes. Also note, that IE and other old browsers -needs [es5-shims](https://github.com/kriskowal/es5-shim) to operate. - - -API ---- - -Here we cover the most 'useful' methods. If you need advanced details (creating -your own tags), see [wiki](https://github.com/nodeca/js-yaml/wiki) and -[examples](https://github.com/nodeca/js-yaml/tree/master/examples) for more -info. - -In node.js JS-YAML automatically registers handlers for `.yml` and `.yaml` -files. You can load them just with `require`. That's mostly equivalent to -calling `load()` on fetched content of a file. Just with one string! - -``` javascript -require('js-yaml'); - -// Get document, or throw exception on error -try { - var doc = require('/home/ixti/example.yml'); - console.log(doc); -} catch (e) { - console.log(e); -} -``` - - -### load (string [ , options ]) - -Parses `string` as single YAML document. Returns a JavaScript object or throws -`YAMLException` on error. - -NOTE: This function **does not** understands multi-document sources, it throws -exception on those. - -options: - -- `filename` _(default: null)_ - string to be used as a file path in - error/warning messages. -- `strict` _(default - false)_ makes the loader to throw errors instead of - warnings. -- `schema` _(default: `DEFAULT_SCHEMA`)_ - specifies a schema to use. - - -### loadAll (string, iterator [ , options ]) - -Same as `load()`, but understands multi-document sources and apply `iterator` to -each document. - -``` javascript -var yaml = require('js-yaml'); - -yaml.loadAll(data, function (doc) { - console.log(doc); -}); -``` - - -### safeLoad (string [ , options ]) - -Same as `load()` but uses `SAFE_SCHEMA` by default - only recommended tags of -YAML specification (no JavaScript-specific tags, e.g. `!!js/regexp`). - - -### safeLoadAll (string, iterator [ , options ]) - -Same as `loadAll()` but uses `SAFE_SCHEMA` by default - only recommended tags of -YAML specification (no JavaScript-specific tags, e.g. `!!js/regexp`). - - -### dump (object [ , options ]) - -Serializes `object` as YAML document. - -options: - -- `indent` _(default: 2)_ - indentation width to use (in spaces). -- `flowLevel` (default: -1) - specifies level of nesting, when to switch from - block to flow style for collections. -1 means block style everwhere -- `styles` - "tag" => "style" map. Each tag may have own set of styles. -- `schema` _(default: `DEFAULT_SCHEMA`)_ specifies a schema to use. - -styles: - -``` none -!!null - "canonical" => "~" - -!!int - "binary" => "0b1", "0b101010", "0b1110001111010" - "octal" => "01", "052", "016172" - "decimal" => "1", "42", "7290" - "hexadecimal" => "0x1", "0x2A", "0x1C7A" - -!!null, !!bool, !!float - "lowercase" => "null", "true", "false", ".nan", '.inf' - "uppercase" => "NULL", "TRUE", "FALSE", ".NAN", '.INF' - "camelcase" => "Null", "True", "False", ".NaN", '.Inf' -``` - -By default, !!int uses `decimal`, and !!null, !!bool, !!float use `lowercase`. - - -### safeDump (object [ , options ]) - -Same as `dump()` but uses `SAFE_SCHEMA` by default - only recommended tags of -YAML specification (no JavaScript-specific tags, e.g. `!!js/regexp`). - - -Supported YAML types --------------------- - -The list of standard YAML tags and corresponding JavaScipt types. See also -[YAML tag discussion](http://pyyaml.org/wiki/YAMLTagDiscussion) and -[YAML types repository](http://yaml.org/type/). - -``` -!!null '' # null -!!bool 'yes' # bool -!!int '3...' # number -!!float '3.14...' # number -!!binary '...base64...' # buffer -!!timestamp 'YYYY-...' # date -!!omap [ ... ] # array of key-value pairs -!!pairs [ ... ] # array or array pairs -!!set { ... } # array of objects with given keys and null values -!!str '...' # string -!!seq [ ... ] # array -!!map { ... } # object -``` - -**JavaScript-specific tags** - -``` -!!js/regexp /pattern/gim # RegExp -!!js/undefined '' # Undefined -!!js/function 'function () {...}' # Function -``` - - - - -## Caveats - -Note, that you use arrays or objects as key in JS-YAML. JS do not allows objects -or array as keys, and stringifies (by calling .toString method) them at the -moment of adding them. - -``` yaml ---- -? [ foo, bar ] -: - baz -? { foo: bar } -: - baz - - baz -``` - -``` javascript -{ "foo,bar": ["baz"], "[object Object]": ["baz", "baz"] } -``` - -Also, reading of properties on implicit block mapping keys is not supported yet. -So, the following YAML document cannot be loaded. - -``` yaml -&anchor foo: - foo: bar - *anchor: duplicate key - baz: bat - *anchor: duplicate key -``` - -## License - -View the [LICENSE](https://github.com/nodeca/js-yaml/blob/master/LICENSE) file -(MIT). diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/bin/js-yaml.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/bin/js-yaml.js deleted file mode 100755 index 5110a4c7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/bin/js-yaml.js +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env node - - -'use strict'; - - -// stdlib -var fs = require('fs'); -var util = require('util'); - - -// 3rd-party -var ArgumentParser = require('argparse').ArgumentParser; - - -// internal -var yaml = require('..'); - - -//////////////////////////////////////////////////////////////////////////////// - - -var cli = new ArgumentParser({ - prog: 'js-yaml', - version: require('../package.json').version, - addHelp: true -}); - - -cli.addArgument(['-c', '--compact'], { - help: 'Display errors in compact mode', - action: 'storeTrue' -}); - - -cli.addArgument(['-j', '--to-json'], { - help: 'Output a non-funky boring JSON', - dest: 'json', - action: 'storeTrue' -}); - - -cli.addArgument(['-t', '--trace'], { - help: 'Show stack trace on error', - action: 'storeTrue' -}); - - -cli.addArgument(['file'], { - help: 'File to read' -}); - - -//////////////////////////////////////////////////////////////////////////////// - - -var options = cli.parseArgs(); - - -//////////////////////////////////////////////////////////////////////////////// - - -fs.readFile(options.file, 'utf8', function (error, input) { - var output, isYaml; - - if (error) { - if ('ENOENT' === error.code) { - console.error('File not found: ' + options.file); - process.exit(2); - } - - console.error( - options.trace && error.stack || - error.message || - String(error)); - - process.exit(1); - } - - try { - output = JSON.parse(input); - isYaml = false; - } catch (error) { - if (error instanceof SyntaxError) { - try { - output = []; - yaml.loadAll(input, function (doc) { output.push(doc); }, {}); - isYaml = true; - - if (0 === output.length) { - output = null; - } else if (1 === output.length) { - output = output[0]; - } - } catch (error) { - if (options.trace && error.stack) { - console.error(error.stack); - } else { - console.error(error.toString(options.compact)); - } - - process.exit(1); - } - } else { - console.error( - options.trace && error.stack || - error.message || - String(error)); - - process.exit(1); - } - } - - if (isYaml) { - if (options.json) { - console.log(JSON.stringify(output, null, ' ')); - } else { - console.log("\n" + util.inspect(output, false, 10, true) + "\n"); - } - } else { - console.log(yaml.dump(output)); - } - - process.exit(0); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.js deleted file mode 100644 index 1cb987c1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.js +++ /dev/null @@ -1,104 +0,0 @@ -'use strict'; - - -var fs = require('fs'); -var path = require('path'); -var util = require('util'); -var yaml = require('../lib/js-yaml'); - - -// Let define a couple of classes... - -function Point(x, y, z) { - this.klass = 'Point'; - this.x = x; - this.y = y; - this.z = z; -} - - -function Space(height, width, points) { - if (points) { - if (!points.every(function (point) { return point instanceof Point; })) { - throw new Error('A non-Point inside a points array!'); - } - } - - this.klass = 'Space'; - this.height = height; - this.width = width; - this.points = points; -} - - -// Let define YAML types to load and dump our Point/Space objects. - -var pointYamlType = new yaml.Type('!point', { - // The information used to load a Point. - loader: { - kind: 'array', // It must be an array. (sequence in YAML) - resolver: function (object) { - // It must contain exactly tree elements. - if (3 === object.length) { - return new Point(object[0], object[1], object[2]); - - // Otherwise, it is NOT a Point. - } else { - return yaml.NIL; - } - } - }, - // The information used to dump a Point. - dumper: { - kind: 'object', // It must be an object but not an array. - instanceOf: Point, // Also, it must be an instance of Point class. - representer: function (point) { - // And it should be represented in YAML as three-element sequence. - return [ point.x, point.y, point.z ]; - } - } -}); - - -var spaceYamlType = new yaml.Type('!space', { - loader: { - kind: 'object', // 'object' here means 'mapping' in YAML. - resolver: function (object) { - return new Space(object.height, object.width, object.points); - } - }, - dumper: { - kind: 'object', - instanceOf: Space - // The representer is omitted here. So, Space objects will be dumped as is. - // That is regular mapping with three key-value pairs but with !space tag. - } -}); - - -// After our types are defined, it's time to join them into a schema. - -var SPACE_SCHEMA = yaml.Schema.create([ spaceYamlType, pointYamlType ]); - - -// And read a document using that schema. - -fs.readFile(path.join(__dirname, 'custom_types.yaml'), 'utf8', function (error, data) { - var loaded; - - if (!error) { - loaded = yaml.load(data, { schema: SPACE_SCHEMA }); - console.log(util.inspect(loaded, false, 20, true)); - } else { - console.error(error.stack || error.message || String(error)); - } -}); - - -// There are some exports to play with this example interactively. - -module.exports.Point = Point; -module.exports.Space = Space; -module.exports.pointYamlType = pointYamlType; -module.exports.spaceYamlType = spaceYamlType; -module.exports.SPACE_SCHEMA = SPACE_SCHEMA; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.yaml b/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.yaml deleted file mode 100644 index 033134f5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/custom_types.yaml +++ /dev/null @@ -1,18 +0,0 @@ -subject: Custom types in JS-YAML -spaces: -- !space - height: 1000 - width: 1000 - points: - - !point [ 10, 43, 23 ] - - !point [ 165, 0, 50 ] - - !point [ 100, 100, 100 ] - -- !space - height: 64 - width: 128 - points: - - !point [ 12, 43, 0 ] - - !point [ 1, 4, 90 ] - -- !space {} # An empty space diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.js deleted file mode 100644 index 7952b18d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - - -var yaml = require('../lib/js-yaml'); -var object = require('./dumper.json'); - - -console.log(yaml.dump(object, { - flowLevel: 3, - styles: { - '!!int' : 'hexadecimal', - '!!null' : 'camelcase' - } -})); - - -// Output: -//============================================================================== -// name: Wizzard -// level: 0x11 -// sanity: Null -// inventory: -// - name: Hat -// features: [magic, pointed] -// traits: {} -// - name: Staff -// features: [] -// traits: {damage: 0xA} -// - name: Cloak -// features: [old] -// traits: {defence: 0x0, comfort: 0x3} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.json deleted file mode 100644 index 9f54c053..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/dumper.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name" : "Wizzard", - "level" : 17, - "sanity" : null, - "inventory" : [ - { - "name" : "Hat", - "features" : [ "magic", "pointed" ], - "traits" : {} - }, - { - "name" : "Staff", - "features" : [], - "traits" : { "damage" : 10 } - }, - { - "name" : "Cloak", - "features" : [ "old" ], - "traits" : { "defence" : 0, "comfort" : 3 } - } - ] -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.js deleted file mode 100644 index 1ce370d8..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - - -var inspect = require('util').inspect; - -// just require jsyaml -require('../lib/js-yaml'); - - -try { - var doc = require(__dirname + '/sample_document.yaml'); - console.log(inspect(doc, false, 10, true)); -} catch (e) { - console.log(e.stack || e.toString()); -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.yaml b/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.yaml deleted file mode 100644 index 4479ee9c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/examples/sample_document.yaml +++ /dev/null @@ -1,197 +0,0 @@ ---- -# Collection Types ############################################################# -################################################################################ - -# http://yaml.org/type/map.html -----------------------------------------------# - -map: - # Unordered set of key: value pairs. - Block style: !!map - Clark : Evans - Ingy : döt Net - Oren : Ben-Kiki - Flow style: !!map { Clark: Evans, Ingy: döt Net, Oren: Ben-Kiki } - -# http://yaml.org/type/omap.html ----------------------------------------------# - -omap: - # Explicitly typed ordered map (dictionary). - Bestiary: !!omap - - aardvark: African pig-like ant eater. Ugly. - - anteater: South-American ant eater. Two species. - - anaconda: South-American constrictor snake. Scaly. - # Etc. - # Flow style - Numbers: !!omap [ one: 1, two: 2, three : 3 ] - -# http://yaml.org/type/pairs.html ---------------------------------------------# - -pairs: - # Explicitly typed pairs. - Block tasks: !!pairs - - meeting: with team. - - meeting: with boss. - - break: lunch. - - meeting: with client. - Flow tasks: !!pairs [ meeting: with team, meeting: with boss ] - -# http://yaml.org/type/set.html -----------------------------------------------# - -set: - # Explicitly typed set. - baseball players: !!set - ? Mark McGwire - ? Sammy Sosa - ? Ken Griffey - # Flow style - baseball teams: !!set { Boston Red Sox, Detroit Tigers, New York Yankees } - -# http://yaml.org/type/seq.html -----------------------------------------------# - -seq: - # Ordered sequence of nodes - Block style: !!seq - - Mercury # Rotates - no light/dark sides. - - Venus # Deadliest. Aptly named. - - Earth # Mostly dirt. - - Mars # Seems empty. - - Jupiter # The king. - - Saturn # Pretty. - - Uranus # Where the sun hardly shines. - - Neptune # Boring. No rings. - - Pluto # You call this a planet? - Flow style: !!seq [ Mercury, Venus, Earth, Mars, # Rocks - Jupiter, Saturn, Uranus, Neptune, # Gas - Pluto ] # Overrated - - -# Scalar Types ################################################################# -################################################################################ - -# http://yaml.org/type/binary.html --------------------------------------------# - -binary: - canonical: !!binary "\ - R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ - OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ - +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ - AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" - generic: !!binary | - R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 - OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ - +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC - AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= - description: - The binary value above is a tiny arrow encoded as a gif image. - -# http://yaml.org/type/bool.html ----------------------------------------------# - -bool: - - true - - True - - TRUE - - false - - False - - FALSE - -# http://yaml.org/type/float.html ---------------------------------------------# - -float: - canonical: 6.8523015e+5 - exponentioal: 685.230_15e+03 - fixed: 685_230.15 - sexagesimal: 190:20:30.15 - negative infinity: -.inf - not a number: .NaN - -# http://yaml.org/type/int.html -----------------------------------------------# - -int: - canonical: 685230 - decimal: +685_230 - octal: 02472256 - hexadecimal: 0x_0A_74_AE - binary: 0b1010_0111_0100_1010_1110 - sexagesimal: 190:20:30 - -# http://yaml.org/type/merge.html ---------------------------------------------# - -merge: - - &CENTER { x: 1, y: 2 } - - &LEFT { x: 0, y: 2 } - - &BIG { r: 10 } - - &SMALL { r: 1 } - - # All the following maps are equal: - - - # Explicit keys - x: 1 - y: 2 - r: 10 - label: nothing - - - # Merge one map - << : *CENTER - r: 10 - label: center - - - # Merge multiple maps - << : [ *CENTER, *BIG ] - label: center/big - - - # Override - << : [ *BIG, *LEFT, *SMALL ] - x: 1 - label: big/left/small - -# http://yaml.org/type/null.html ----------------------------------------------# - -null: - # This mapping has four keys, - # one has a value. - empty: - canonical: ~ - english: null - ~: null key - # This sequence has five - # entries, two have values. - sparse: - - ~ - - 2nd entry - - - - 4th entry - - Null - -# http://yaml.org/type/str.html -----------------------------------------------# - -string: abcd - -# http://yaml.org/type/timestamp.html -----------------------------------------# - -timestamp: - canonical: 2001-12-15T02:59:43.1Z - valid iso8601: 2001-12-14t21:59:43.10-05:00 - space separated: 2001-12-14 21:59:43.10 -5 - no time zone (Z): 2001-12-15 2:59:43.10 - date (00:00:00Z): 2002-12-14 - - -# JavaScript Specific Types #################################################### -################################################################################ - -# https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp - -regexp: - simple: !!js/regexp foobar - modifiers: !!js/regexp /foobar/mi - -# https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/undefined - -undefined: !!js/undefined ~ - -# https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function - -function: !!js/function > - function foobar() { - return 'Wow! JS-YAML Rocks!'; - } diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/index.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/index.js deleted file mode 100644 index 40606ddc..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/js-yaml.js'); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml.js deleted file mode 100644 index a5146a32..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - - -var loader = require('./js-yaml/loader'); -var dumper = require('./js-yaml/dumper'); - - -function deprecated(name) { - return function () { - throw new Error('Function ' + name + ' is deprecated and cannot be used.'); - }; -} - - -module.exports.Type = require('./js-yaml/type'); -module.exports.Schema = require('./js-yaml/schema'); -module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/minimal'); -module.exports.SAFE_SCHEMA = require('./js-yaml/schema/safe'); -module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default'); -module.exports.load = loader.load; -module.exports.loadAll = loader.loadAll; -module.exports.safeLoad = loader.safeLoad; -module.exports.safeLoadAll = loader.safeLoadAll; -module.exports.dump = dumper.dump; -module.exports.safeDump = dumper.safeDump; -module.exports.YAMLException = require('./js-yaml/exception'); -module.exports.scan = deprecated('scan'); -module.exports.parse = deprecated('parse'); -module.exports.compose = deprecated('compose'); -module.exports.addConstructor = deprecated('addConstructor'); - - -require('./js-yaml/require'); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/common.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/common.js deleted file mode 100644 index cc7f824c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/common.js +++ /dev/null @@ -1,60 +0,0 @@ -'use strict'; - - -var NIL = {}; - - -function isNothing(subject) { - return (undefined === subject) || (null === subject); -} - - -function isObject(subject) { - return ('object' === typeof subject) && (null !== subject); -} - - -function toArray(sequence) { - if (Array.isArray(sequence)) { - return sequence; - } else if (isNothing(sequence)) { - return []; - } else { - return [ sequence ]; - } -} - - -function extend(target, source) { - var index, length, key, sourceKeys; - - if (source) { - sourceKeys = Object.keys(source); - - for (index = 0, length = sourceKeys.length; index < length; index += 1) { - key = sourceKeys[index]; - target[key] = source[key]; - } - } - - return target; -} - - -function repeat(string, count) { - var result = '', cycle; - - for (cycle = 0; cycle < count; cycle += 1) { - result += string; - } - - return result; -} - - -module.exports.NIL = NIL; -module.exports.isNothing = isNothing; -module.exports.isObject = isObject; -module.exports.toArray = toArray; -module.exports.repeat = repeat; -module.exports.extend = extend; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/dumper.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/dumper.js deleted file mode 100644 index 2385f569..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/dumper.js +++ /dev/null @@ -1,437 +0,0 @@ -'use strict'; - - -var common = require('./common'); -var NIL = common.NIL; -var YAMLException = require('./exception'); -var DEFAULT_SCHEMA = require('./schema/default'); -var SAFE_SCHEMA = require('./schema/safe'); - - -var _hasOwnProperty = Object.prototype.hasOwnProperty; - - -var CHAR_TAB = 0x09; /* Tab */ -var CHAR_LINE_FEED = 0x0A; /* LF */ -var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ -var CHAR_SPACE = 0x20; /* Space */ -var CHAR_EXCLAMATION = 0x21; /* ! */ -var CHAR_DOUBLE_QUOTE = 0x22; /* " */ -var CHAR_SHARP = 0x23; /* # */ -var CHAR_PERCENT = 0x25; /* % */ -var CHAR_AMPERSAND = 0x26; /* & */ -var CHAR_SINGLE_QUOTE = 0x27; /* ' */ -var CHAR_ASTERISK = 0x2A; /* * */ -var CHAR_COMMA = 0x2C; /* , */ -var CHAR_MINUS = 0x2D; /* - */ -var CHAR_COLON = 0x3A; /* : */ -var CHAR_GREATER_THAN = 0x3E; /* > */ -var CHAR_QUESTION = 0x3F; /* ? */ -var CHAR_COMMERCIAL_AT = 0x40; /* @ */ -var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ -var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ -var CHAR_GRAVE_ACCENT = 0x60; /* ` */ -var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ -var CHAR_VERTICAL_LINE = 0x7C; /* | */ -var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ - - -var ESCAPE_SEQUENCES = {}; - -ESCAPE_SEQUENCES[0x00] = '\\0'; -ESCAPE_SEQUENCES[0x07] = '\\a'; -ESCAPE_SEQUENCES[0x08] = '\\b'; -ESCAPE_SEQUENCES[0x09] = '\\t'; -ESCAPE_SEQUENCES[0x0A] = '\\n'; -ESCAPE_SEQUENCES[0x0B] = '\\v'; -ESCAPE_SEQUENCES[0x0C] = '\\f'; -ESCAPE_SEQUENCES[0x0D] = '\\r'; -ESCAPE_SEQUENCES[0x1B] = '\\e'; -ESCAPE_SEQUENCES[0x22] = '\\"'; -ESCAPE_SEQUENCES[0x5C] = '\\\\'; -ESCAPE_SEQUENCES[0x85] = '\\N'; -ESCAPE_SEQUENCES[0xA0] = '\\_'; -ESCAPE_SEQUENCES[0x2028] = '\\L'; -ESCAPE_SEQUENCES[0x2029] = '\\P'; - - -function kindOf(object) { - var kind = typeof object; - - if (null === object) { - return 'null'; - } else if ('number' === kind) { - return 0 === object % 1 ? 'integer' : 'float'; - } else if ('object' === kind && Array.isArray(object)) { - return 'array'; - } else { - return kind; - } -} - - -function compileStyleMap(schema, map) { - var result, keys, index, length, tag, style, type; - - if (null === map) { - return {}; - } - - result = {}; - keys = Object.keys(map); - - for (index = 0, length = keys.length; index < length; index += 1) { - tag = keys[index]; - style = String(map[tag]); - - if ('!!' === tag.slice(0, 2)) { - tag = 'tag:yaml.org,2002:' + tag.slice(2); - } - - type = schema.compiledTypeMap[tag]; - - if (type && type.dumper) { - if (_hasOwnProperty.call(type.dumper.styleAliases, style)) { - style = type.dumper.styleAliases[style]; - } - } - - result[tag] = style; - } - - return result; -} - - -function encodeHex(character) { - var string, handle, length; - - string = character.toString(16).toUpperCase(); - - if (character <= 0xFF) { - handle = 'x'; - length = 2; - } else if (character <= 0xFFFF) { - handle = 'u'; - length = 4; - } else if (character <= 0xFFFFFFFF) { - handle = 'U'; - length = 8; - } else { - throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); - } - - return '\\' + handle + common.repeat('0', length - string.length) + string; -} - - -function dump(input, options) { - options = options || {}; - - var schema = options['schema'] || DEFAULT_SCHEMA, - indent = Math.max(1, (options['indent'] || 2)), - flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']), - styleMap = compileStyleMap(schema, options['styles'] || null), - - implicitTypes = schema.compiledImplicit, - explicitTypes = schema.compiledExplicit, - - kind, - tag, - result; - - function generateNextLine(level) { - return '\n' + common.repeat(' ', indent * level); - } - - function testImplicitResolving(object) { - var index, length, type; - - for (index = 0, length = implicitTypes.length; index < length; index += 1) { - type = implicitTypes[index]; - - if (null !== type.loader && - NIL !== type.loader.resolver(object, false)) { - return true; - } - } - - return false; - } - - function writeScalar(object) { - var isQuoted, checkpoint, position, length, character; - - result = ''; - isQuoted = false; - checkpoint = 0; - - if (0 === object.length || - CHAR_SPACE === object.charCodeAt(0) || - CHAR_SPACE === object.charCodeAt(object.length - 1)) { - isQuoted = true; - } - - for (position = 0, length = object.length; position < length; position += 1) { - character = object.charCodeAt(position); - - if (!isQuoted) { - if (CHAR_TAB === character || - CHAR_LINE_FEED === character || - CHAR_CARRIAGE_RETURN === character || - CHAR_COMMA === character || - CHAR_LEFT_SQUARE_BRACKET === character || - CHAR_RIGHT_SQUARE_BRACKET === character || - CHAR_LEFT_CURLY_BRACKET === character || - CHAR_RIGHT_CURLY_BRACKET === character || - CHAR_SHARP === character || - CHAR_AMPERSAND === character || - CHAR_ASTERISK === character || - CHAR_EXCLAMATION === character || - CHAR_VERTICAL_LINE === character || - CHAR_GREATER_THAN === character || - CHAR_SINGLE_QUOTE === character || - CHAR_DOUBLE_QUOTE === character || - CHAR_PERCENT === character || - CHAR_COMMERCIAL_AT === character || - CHAR_GRAVE_ACCENT === character || - CHAR_QUESTION === character || - CHAR_COLON === character || - CHAR_MINUS === character) { - isQuoted = true; - } - } - - if (ESCAPE_SEQUENCES[character] || - !((0x00020 <= character && character <= 0x00007E) || - (0x00085 === character) || - (0x000A0 <= character && character <= 0x00D7FF) || - (0x0E000 <= character && character <= 0x00FFFD) || - (0x10000 <= character && character <= 0x10FFFF))) { - result += object.slice(checkpoint, position); - result += ESCAPE_SEQUENCES[character] || encodeHex(character); - checkpoint = position + 1; - isQuoted = true; - } - } - - if (checkpoint < position) { - result += object.slice(checkpoint, position); - } - - if (!isQuoted && testImplicitResolving(result)) { - isQuoted = true; - } - - if (isQuoted) { - result = '"' + result + '"'; - } - } - - function writeFlowSequence(level, object) { - var _result = '', - _tag = tag, - index, - length; - - for (index = 0, length = object.length; index < length; index += 1) { - if (0 !== index) { - _result += ', '; - } - - writeNode(level, object[index], false, false); - _result += result; - } - - tag = _tag; - result = '[' + _result + ']'; - } - - function writeBlockSequence(level, object, compact) { - var _result = '', - _tag = tag, - index, - length; - - for (index = 0, length = object.length; index < length; index += 1) { - if (!compact || 0 !== index) { - _result += generateNextLine(level); - } - - writeNode(level + 1, object[index], true, true); - _result += '- ' + result; - } - - tag = _tag; - result = _result; - } - - function writeFlowMapping(level, object) { - var _result = '', - _tag = tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue; - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - if (0 !== index) { - _result += ', '; - } - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - writeNode(level, objectKey, false, false); - - if (result.length > 1024) { - _result += '? '; - } - - _result += result + ': '; - writeNode(level, objectValue, false, false); - _result += result; - } - - tag = _tag; - result = '{' + _result + '}'; - } - - function writeBlockMapping(level, object, compact) { - var _result = '', - _tag = tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - explicitPair; - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - if (!compact || 0 !== index) { - _result += generateNextLine(level); - } - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - writeNode(level + 1, objectKey, true, true); - explicitPair = (null !== tag && '?' !== tag && result.length <= 1024); - - if (explicitPair) { - _result += '? '; - } - - _result += result; - - if (explicitPair) { - _result += generateNextLine(level); - } - - writeNode(level + 1, objectValue, true, explicitPair); - _result += ': ' + result; - } - - tag = _tag; - result = _result; - } - - function detectType(object, explicit) { - var _result, typeList, index, length, type, style; - - typeList = explicit ? explicitTypes : implicitTypes; - kind = kindOf(object); - - for (index = 0, length = typeList.length; index < length; index += 1) { - type = typeList[index]; - - if ((null !== type.dumper) && - (null === type.dumper.kind || kind === type.dumper.kind) && - (null === type.dumper.instanceOf || object instanceof type.dumper.instanceOf) && - (null === type.dumper.predicate || type.dumper.predicate(object))) { - tag = explicit ? type.tag : '?'; - - if (null !== type.dumper.representer) { - style = styleMap[type.tag] || type.dumper.defaultStyle; - - if ('function' === typeof type.dumper.representer) { - _result = type.dumper.representer(object, style); - } else if (_hasOwnProperty.call(type.dumper.representer, style)) { - _result = type.dumper.representer[style](object, style); - } else { - throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); - } - - if (NIL !== _result) { - kind = kindOf(_result); - result = _result; - } else { - if (explicit) { - throw new YAMLException('cannot represent an object of !<' + type.tag + '> type'); - } else { - continue; - } - } - } - - return true; - } - } - - return false; - } - - function writeNode(level, object, block, compact) { - tag = null; - result = object; - - if (!detectType(object, false)) { - detectType(object, true); - } - - if (block) { - block = (0 > flowLevel || flowLevel > level); - } - - if ((null !== tag && '?' !== tag) || (2 !== indent && level > 0)) { - compact = false; - } - - if ('object' === kind) { - if (block && (0 !== Object.keys(result).length)) { - writeBlockMapping(level, result, compact); - } else { - writeFlowMapping(level, result); - } - } else if ('array' === kind) { - if (block && (0 !== result.length)) { - writeBlockSequence(level, result, compact); - } else { - writeFlowSequence(level, result); - } - } else if ('string' === kind) { - if ('?' !== tag) { - writeScalar(result); - } - } else { - throw new YAMLException('unacceptabe kind of an object to dump (' + kind + ')'); - } - - if (null !== tag && '?' !== tag) { - result = '!<' + tag + '> ' + result; - } - } - - writeNode(0, input, true, true); - return result + '\n'; -} - - -function safeDump(input, options) { - return dump(input, common.extend({ schema: SAFE_SCHEMA }, options)); -} - - -module.exports.dump = dump; -module.exports.safeDump = safeDump; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/exception.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/exception.js deleted file mode 100644 index 479ba887..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/exception.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - - -function YAMLException(reason, mark) { - this.name = 'YAMLException'; - this.reason = reason; - this.mark = mark; - this.message = this.toString(false); -} - - -YAMLException.prototype.toString = function toString(compact) { - var result; - - result = 'JS-YAML: ' + (this.reason || '(unknown reason)'); - - if (!compact && this.mark) { - result += ' ' + this.mark.toString(); - } - - return result; -}; - - -module.exports = YAMLException; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/loader.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/loader.js deleted file mode 100644 index bdc71d1e..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/loader.js +++ /dev/null @@ -1,1549 +0,0 @@ -'use strict'; - - -var common = require('./common'); -var YAMLException = require('./exception'); -var Mark = require('./mark'); -var NIL = common.NIL; -var SAFE_SCHEMA = require('./schema/safe'); -var DEFAULT_SCHEMA = require('./schema/default'); - - -var _hasOwnProperty = Object.prototype.hasOwnProperty; - - -var KIND_STRING = 'string'; -var KIND_ARRAY = 'array'; -var KIND_OBJECT = 'object'; - - -var CONTEXT_FLOW_IN = 1; -var CONTEXT_FLOW_OUT = 2; -var CONTEXT_BLOCK_IN = 3; -var CONTEXT_BLOCK_OUT = 4; - - -var CHOMPING_CLIP = 1; -var CHOMPING_STRIP = 2; -var CHOMPING_KEEP = 3; - - -var CHAR_TAB = 0x09; /* Tab */ -var CHAR_LINE_FEED = 0x0A; /* LF */ -var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ -var CHAR_SPACE = 0x20; /* Space */ -var CHAR_EXCLAMATION = 0x21; /* ! */ -var CHAR_DOUBLE_QUOTE = 0x22; /* " */ -var CHAR_SHARP = 0x23; /* # */ -var CHAR_PERCENT = 0x25; /* % */ -var CHAR_AMPERSAND = 0x26; /* & */ -var CHAR_SINGLE_QUOTE = 0x27; /* ' */ -var CHAR_ASTERISK = 0x2A; /* * */ -var CHAR_PLUS = 0x2B; /* + */ -var CHAR_COMMA = 0x2C; /* , */ -var CHAR_MINUS = 0x2D; /* - */ -var CHAR_DOT = 0x2E; /* . */ -var CHAR_SLASH = 0x2F; /* / */ -var CHAR_DIGIT_ZERO = 0x30; /* 0 */ -var CHAR_DIGIT_ONE = 0x31; /* 1 */ -var CHAR_DIGIT_NINE = 0x39; /* 9 */ -var CHAR_COLON = 0x3A; /* : */ -var CHAR_LESS_THAN = 0x3C; /* < */ -var CHAR_GREATER_THAN = 0x3E; /* > */ -var CHAR_QUESTION = 0x3F; /* ? */ -var CHAR_COMMERCIAL_AT = 0x40; /* @ */ -var CHAR_CAPITAL_A = 0x41; /* A */ -var CHAR_CAPITAL_F = 0x46; /* F */ -var CHAR_CAPITAL_L = 0x4C; /* L */ -var CHAR_CAPITAL_N = 0x4E; /* N */ -var CHAR_CAPITAL_P = 0x50; /* P */ -var CHAR_CAPITAL_U = 0x55; /* U */ -var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ -var CHAR_BACKSLASH = 0x5C; /* \ */ -var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ -var CHAR_UNDERSCORE = 0x5F; /* _ */ -var CHAR_GRAVE_ACCENT = 0x60; /* ` */ -var CHAR_SMALL_A = 0x61; /* a */ -var CHAR_SMALL_B = 0x62; /* b */ -var CHAR_SMALL_E = 0x65; /* e */ -var CHAR_SMALL_F = 0x66; /* f */ -var CHAR_SMALL_N = 0x6E; /* n */ -var CHAR_SMALL_R = 0x72; /* r */ -var CHAR_SMALL_T = 0x74; /* t */ -var CHAR_SMALL_U = 0x75; /* u */ -var CHAR_SMALL_V = 0x76; /* v */ -var CHAR_SMALL_X = 0x78; /* x */ -var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ -var CHAR_VERTICAL_LINE = 0x7C; /* | */ -var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ - - -var SIMPLE_ESCAPE_SEQUENCES = {}; - -SIMPLE_ESCAPE_SEQUENCES[CHAR_DIGIT_ZERO] = '\x00'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_A] = '\x07'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_B] = '\x08'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_T] = '\x09'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_TAB] = '\x09'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_N] = '\x0A'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_V] = '\x0B'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_F] = '\x0C'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_R] = '\x0D'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SMALL_E] = '\x1B'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SPACE] = ' '; -SIMPLE_ESCAPE_SEQUENCES[CHAR_DOUBLE_QUOTE] = '\x22'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_SLASH] = '/'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_BACKSLASH] = '\x5C'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_N] = '\x85'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_UNDERSCORE] = '\xA0'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_L] = '\u2028'; -SIMPLE_ESCAPE_SEQUENCES[CHAR_CAPITAL_P] = '\u2029'; - - -var HEXADECIMAL_ESCAPE_SEQUENCES = {}; - -HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_X] = 2; -HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_SMALL_U] = 4; -HEXADECIMAL_ESCAPE_SEQUENCES[CHAR_CAPITAL_U] = 8; - - -var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/; -var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; -var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; -var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; -var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; - - -function loadAll(input, output, options) { - options = options || {}; - - var filename = options['filename'] || null, - schema = options['schema'] || DEFAULT_SCHEMA, - resolve = options['resolve'] || true, - validate = options['validate'] || true, - strict = options['strict'] || false, - legacy = options['legacy'] || false, - - directiveHandlers = {}, - implicitTypes = schema.compiledImplicit, - typeMap = schema.compiledTypeMap, - - length = input.length, - position = 0, - line = 0, - lineStart = 0, - lineIndent = 0, - character = input.charCodeAt(position), - - version, - checkLineBreaks, - tagMap, - anchorMap, - tag, - anchor, - kind, - result; - - function generateError(message) { - return new YAMLException( - message, - new Mark(filename, input, position, line, (position - lineStart))); - } - - function throwError(message) { - throw generateError(message); - } - - function throwWarning(message) { - var error = generateError(message); - - if (strict) { - throw error; - } else { - console.warn(error.toString()); - } - } - - directiveHandlers['YAML'] = function handleYamlDirective(name, args) { - var match, major, minor; - - if (null !== version) { - throwError('duplication of %YAML directive'); - } - - if (1 !== args.length) { - throwError('YAML directive accepts exactly one argument'); - } - - match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); - - if (null === match) { - throwError('ill-formed argument of the YAML directive'); - } - - major = parseInt(match[1], 10); - minor = parseInt(match[2], 10); - - if (1 !== major) { - throwError('unacceptable YAML version of the document'); - } - - version = args[0]; - checkLineBreaks = (minor < 2); - - if (1 !== minor && 2 !== minor) { - throwWarning('unsupported YAML version of the document'); - } - }; - - directiveHandlers['TAG'] = function handleTagDirective(name, args) { - var handle, prefix; - - if (2 !== args.length) { - throwError('TAG directive accepts exactly two arguments'); - } - - handle = args[0]; - prefix = args[1]; - - if (!PATTERN_TAG_HANDLE.test(handle)) { - throwError('ill-formed tag handle (first argument) of the TAG directive'); - } - - if (_hasOwnProperty.call(tagMap, handle)) { - throwError('there is a previously declared suffix for "' + handle + '" tag handle'); - } - - if (!PATTERN_TAG_URI.test(prefix)) { - throwError('ill-formed tag prefix (second argument) of the TAG directive'); - } - - tagMap[handle] = prefix; - }; - - function captureSegment(start, end, checkJson) { - var _position, _length, _character, _result; - - if (start < end) { - _result = input.slice(start, end); - - if (checkJson && validate) { - for (_position = 0, _length = _result.length; - _position < _length; - _position += 1) { - _character = _result.charCodeAt(_position); - if (!(0x09 === _character || - 0x20 <= _character && _character <= 0x10FFFF)) { - throwError('expected valid JSON character'); - } - } - } - - result += _result; - } - } - - function mergeMappings(destination, source) { - var sourceKeys, key, index, quantity; - - if (!common.isObject(source)) { - throwError('cannot merge mappings; the provided source object is unacceptable'); - } - - sourceKeys = Object.keys(source); - - for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { - key = sourceKeys[index]; - - if (!_hasOwnProperty.call(destination, key)) { - destination[key] = source[key]; - } - } - } - - function storeMappingPair(_result, keyTag, keyNode, valueNode) { - var index, quantity; - - keyNode = String(keyNode); - - if (null === _result) { - _result = {}; - } - - if ('tag:yaml.org,2002:merge' === keyTag) { - if (Array.isArray(valueNode)) { - for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { - mergeMappings(_result, valueNode[index]); - } - } else { - mergeMappings(_result, valueNode); - } - } else { - _result[keyNode] = valueNode; - } - - return _result; - } - - function readLineBreak() { - if (CHAR_LINE_FEED === character) { - position += 1; - } else if (CHAR_CARRIAGE_RETURN === character) { - if (CHAR_LINE_FEED === input.charCodeAt(position + 1)) { - position += 2; - } else { - position += 1; - } - } else { - throwError('a line break is expected'); - } - - line += 1; - lineStart = position; - character = input.charCodeAt(position); - } - - function skipSeparationSpace(allowComments, checkIndent) { - var lineBreaks = 0; - - while (position < length) { - while (CHAR_SPACE === character || CHAR_TAB === character) { - character = input.charCodeAt(++position); - } - - if (allowComments && CHAR_SHARP === character) { - do { character = input.charCodeAt(++position); } - while (position < length && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character); - } - - if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) { - readLineBreak(); - lineBreaks += 1; - lineIndent = 0; - - while (CHAR_SPACE === character) { - lineIndent += 1; - character = input.charCodeAt(++position); - } - - if (lineIndent < checkIndent) { - throwWarning('deficient indentation'); - } - } else { - break; - } - } - - return lineBreaks; - } - - function testDocumentSeparator() { - var _position, _character; - - if (position === lineStart && - (CHAR_MINUS === character || CHAR_DOT === character) && - input.charCodeAt(position + 1) === character && - input.charCodeAt(position + 2) === character) { - - _position = position + 3; - _character = input.charCodeAt(_position); - - if (_position >= length || - CHAR_SPACE === _character || - CHAR_TAB === _character || - CHAR_LINE_FEED === _character || - CHAR_CARRIAGE_RETURN === _character) { - return true; - } - } - - return false; - } - - function writeFoldedLines(count) { - if (1 === count) { - result += ' '; - } else if (count > 1) { - result += common.repeat('\n', count - 1); - } - } - - function readPlainScalar(nodeIndent, withinFlowCollection) { - var preceding, - following, - captureStart, - captureEnd, - hasPendingContent, - _line, - _lineStart, - _lineIndent, - _kind = kind, - _result = result; - - if (CHAR_SPACE === character || - CHAR_TAB === character || - CHAR_LINE_FEED === character || - CHAR_CARRIAGE_RETURN === character || - CHAR_COMMA === character || - CHAR_LEFT_SQUARE_BRACKET === character || - CHAR_RIGHT_SQUARE_BRACKET === character || - CHAR_LEFT_CURLY_BRACKET === character || - CHAR_RIGHT_CURLY_BRACKET === character || - CHAR_SHARP === character || - CHAR_AMPERSAND === character || - CHAR_ASTERISK === character || - CHAR_EXCLAMATION === character || - CHAR_VERTICAL_LINE === character || - CHAR_GREATER_THAN === character || - CHAR_SINGLE_QUOTE === character || - CHAR_DOUBLE_QUOTE === character || - CHAR_PERCENT === character || - CHAR_COMMERCIAL_AT === character || - CHAR_GRAVE_ACCENT === character) { - return false; - } - - if (CHAR_QUESTION === character || - CHAR_MINUS === character) { - following = input.charCodeAt(position + 1); - - if (CHAR_SPACE === following || - CHAR_TAB === following || - CHAR_LINE_FEED === following || - CHAR_CARRIAGE_RETURN === following || - withinFlowCollection && - (CHAR_COMMA === following || - CHAR_LEFT_SQUARE_BRACKET === following || - CHAR_RIGHT_SQUARE_BRACKET === following || - CHAR_LEFT_CURLY_BRACKET === following || - CHAR_RIGHT_CURLY_BRACKET === following)) { - return false; - } - } - - kind = KIND_STRING; - result = ''; - captureStart = captureEnd = position; - hasPendingContent = false; - - while (position < length) { - if (CHAR_COLON === character) { - following = input.charCodeAt(position + 1); - - if (CHAR_SPACE === following || - CHAR_TAB === following || - CHAR_LINE_FEED === following || - CHAR_CARRIAGE_RETURN === following || - withinFlowCollection && - (CHAR_COMMA === following || - CHAR_LEFT_SQUARE_BRACKET === following || - CHAR_RIGHT_SQUARE_BRACKET === following || - CHAR_LEFT_CURLY_BRACKET === following || - CHAR_RIGHT_CURLY_BRACKET === following)) { - break; - } - - } else if (CHAR_SHARP === character) { - preceding = input.charCodeAt(position - 1); - - if (CHAR_SPACE === preceding || - CHAR_TAB === preceding || - CHAR_LINE_FEED === preceding || - CHAR_CARRIAGE_RETURN === preceding) { - break; - } - - } else if ((position === lineStart && testDocumentSeparator()) || - withinFlowCollection && - (CHAR_COMMA === character || - CHAR_LEFT_SQUARE_BRACKET === character || - CHAR_RIGHT_SQUARE_BRACKET === character || - CHAR_LEFT_CURLY_BRACKET === character || - CHAR_RIGHT_CURLY_BRACKET === character)) { - break; - - } else if (CHAR_LINE_FEED === character || - CHAR_CARRIAGE_RETURN === character) { - _line = line; - _lineStart = lineStart; - _lineIndent = lineIndent; - skipSeparationSpace(false, -1); - - if (lineIndent >= nodeIndent) { - hasPendingContent = true; - continue; - } else { - position = captureEnd; - line = _line; - lineStart = _lineStart; - lineIndent = _lineIndent; - character = input.charCodeAt(position); - break; - } - } - - if (hasPendingContent) { - captureSegment(captureStart, captureEnd, false); - writeFoldedLines(line - _line); - captureStart = captureEnd = position; - hasPendingContent = false; - } - - if (CHAR_SPACE !== character && CHAR_TAB !== character) { - captureEnd = position + 1; - } - - character = input.charCodeAt(++position); - } - - captureSegment(captureStart, captureEnd, false); - - if (result) { - return true; - } else { - kind = _kind; - result = _result; - return false; - } - } - - function readSingleQuotedScalar(nodeIndent) { - var captureStart, captureEnd; - - if (CHAR_SINGLE_QUOTE !== character) { - return false; - } - - kind = KIND_STRING; - result = ''; - character = input.charCodeAt(++position); - captureStart = captureEnd = position; - - while (position < length) { - if (CHAR_SINGLE_QUOTE === character) { - captureSegment(captureStart, position, true); - character = input.charCodeAt(++position); - - if (CHAR_SINGLE_QUOTE === character) { - captureStart = captureEnd = position; - character = input.charCodeAt(++position); - } else { - return true; - } - - } else if (CHAR_LINE_FEED === character || - CHAR_CARRIAGE_RETURN === character) { - captureSegment(captureStart, captureEnd, true); - writeFoldedLines(skipSeparationSpace(false, nodeIndent)); - captureStart = captureEnd = position; - character = input.charCodeAt(position); - - } else if (position === lineStart && testDocumentSeparator()) { - throwError('unexpected end of the document within a single quoted scalar'); - - } else { - character = input.charCodeAt(++position); - captureEnd = position; - } - } - - throwError('unexpected end of the stream within a single quoted scalar'); - } - - function readDoubleQuotedScalar(nodeIndent) { - var captureStart, - captureEnd, - hexLength, - hexIndex, - hexOffset, - hexResult; - - if (CHAR_DOUBLE_QUOTE !== character) { - return false; - } - - kind = KIND_STRING; - result = ''; - character = input.charCodeAt(++position); - captureStart = captureEnd = position; - - while (position < length) { - if (CHAR_DOUBLE_QUOTE === character) { - captureSegment(captureStart, position, true); - character = input.charCodeAt(++position); - return true; - - } else if (CHAR_BACKSLASH === character) { - captureSegment(captureStart, position, true); - character = input.charCodeAt(++position); - - if (CHAR_LINE_FEED === character || - CHAR_CARRIAGE_RETURN === character) { - skipSeparationSpace(false, nodeIndent); - - } else if (SIMPLE_ESCAPE_SEQUENCES[character]) { - result += SIMPLE_ESCAPE_SEQUENCES[character]; - character = input.charCodeAt(++position); - - } else if (HEXADECIMAL_ESCAPE_SEQUENCES[character]) { - hexLength = HEXADECIMAL_ESCAPE_SEQUENCES[character]; - hexResult = 0; - - for (hexIndex = 1; hexIndex <= hexLength; hexIndex += 1) { - hexOffset = (hexLength - hexIndex) * 4; - character = input.charCodeAt(++position); - - if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) { - hexResult |= (character - CHAR_DIGIT_ZERO) << hexOffset; - - } else if (CHAR_CAPITAL_A <= character && character <= CHAR_CAPITAL_F) { - hexResult |= (character - CHAR_CAPITAL_A + 10) << hexOffset; - - } else if (CHAR_SMALL_A <= character && character <= CHAR_SMALL_F) { - hexResult |= (character - CHAR_SMALL_A + 10) << hexOffset; - - } else { - throwError('expected hexadecimal character'); - } - } - - result += String.fromCharCode(hexResult); - character = input.charCodeAt(++position); - - } else { - throwError('unknown escape sequence'); - } - - captureStart = captureEnd = position; - - } else if (CHAR_LINE_FEED === character || - CHAR_CARRIAGE_RETURN === character) { - captureSegment(captureStart, captureEnd, true); - writeFoldedLines(skipSeparationSpace(false, nodeIndent)); - captureStart = captureEnd = position; - character = input.charCodeAt(position); - - } else if (position === lineStart && testDocumentSeparator()) { - throwError('unexpected end of the document within a double quoted scalar'); - - } else { - character = input.charCodeAt(++position); - captureEnd = position; - } - } - - throwError('unexpected end of the stream within a double quoted scalar'); - } - - function readFlowCollection(nodeIndent) { - var readNext = true, - _line, - _tag = tag, - _result, - following, - terminator, - isPair, - isExplicitPair, - isMapping, - keyNode, - keyTag, - valueNode; - - switch (character) { - case CHAR_LEFT_SQUARE_BRACKET: - terminator = CHAR_RIGHT_SQUARE_BRACKET; - isMapping = false; - _result = []; - break; - - case CHAR_LEFT_CURLY_BRACKET: - terminator = CHAR_RIGHT_CURLY_BRACKET; - isMapping = true; - _result = {}; - break; - - default: - return false; - } - - if (null !== anchor) { - anchorMap[anchor] = _result; - } - - character = input.charCodeAt(++position); - - while (position < length) { - skipSeparationSpace(true, nodeIndent); - - if (character === terminator) { - character = input.charCodeAt(++position); - tag = _tag; - kind = isMapping ? KIND_OBJECT : KIND_ARRAY; - result = _result; - return true; - } else if (!readNext) { - throwError('missed comma between flow collection entries'); - } - - keyTag = keyNode = valueNode = null; - isPair = isExplicitPair = false; - - if (CHAR_QUESTION === character) { - following = input.charCodeAt(position + 1); - - if (CHAR_SPACE === following || - CHAR_TAB === following || - CHAR_LINE_FEED === following || - CHAR_CARRIAGE_RETURN === following) { - isPair = isExplicitPair = true; - position += 1; - character = following; - skipSeparationSpace(true, nodeIndent); - } - } - - _line = line; - composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true); - keyTag = tag; - keyNode = result; - - if ((isExplicitPair || line === _line) && CHAR_COLON === character) { - isPair = true; - character = input.charCodeAt(++position); - skipSeparationSpace(true, nodeIndent); - composeNode(nodeIndent, CONTEXT_FLOW_IN, false, true); - valueNode = result; - } - - if (isMapping) { - storeMappingPair(_result, keyTag, keyNode, valueNode); - } else if (isPair) { - _result.push(storeMappingPair(null, keyTag, keyNode, valueNode)); - } else { - _result.push(keyNode); - } - - skipSeparationSpace(true, nodeIndent); - - if (CHAR_COMMA === character) { - readNext = true; - character = input.charCodeAt(++position); - } else { - readNext = false; - } - } - - throwError('unexpected end of the stream within a flow collection'); - } - - function readBlockScalar(nodeIndent) { - var captureStart, - folding, - chomping = CHOMPING_CLIP, - detectedIndent = false, - textIndent = nodeIndent, - emptyLines = -1; - - switch (character) { - case CHAR_VERTICAL_LINE: - folding = false; - break; - - case CHAR_GREATER_THAN: - folding = true; - break; - - default: - return false; - } - - kind = KIND_STRING; - result = ''; - - while (position < length) { - character = input.charCodeAt(++position); - - if (CHAR_PLUS === character || CHAR_MINUS === character) { - if (CHOMPING_CLIP === chomping) { - chomping = (CHAR_PLUS === character) ? CHOMPING_KEEP : CHOMPING_STRIP; - } else { - throwError('repeat of a chomping mode identifier'); - } - - } else if (CHAR_DIGIT_ZERO <= character && character <= CHAR_DIGIT_NINE) { - if (CHAR_DIGIT_ZERO === character) { - throwError('bad explicit indentation width of a block scalar; it cannot be less than one'); - } else if (!detectedIndent) { - textIndent = nodeIndent + (character - CHAR_DIGIT_ONE); - detectedIndent = true; - } else { - throwError('repeat of an indentation width identifier'); - } - - } else { - break; - } - } - - if (CHAR_SPACE === character || CHAR_TAB === character) { - do { character = input.charCodeAt(++position); } - while (CHAR_SPACE === character || CHAR_TAB === character); - - if (CHAR_SHARP === character) { - do { character = input.charCodeAt(++position); } - while (position < length && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character); - } - } - - while (position < length) { - readLineBreak(); - lineIndent = 0; - - while ((!detectedIndent || lineIndent < textIndent) && - (CHAR_SPACE === character)) { - lineIndent += 1; - character = input.charCodeAt(++position); - } - - if (!detectedIndent && lineIndent > textIndent) { - textIndent = lineIndent; - } - - if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) { - emptyLines += 1; - continue; - } - - // End of the scalar. Perform the chomping. - if (lineIndent < textIndent) { - if (CHOMPING_KEEP === chomping) { - result += common.repeat('\n', emptyLines + 1); - } else if (CHOMPING_CLIP === chomping) { - result += '\n'; - } - break; - } - - detectedIndent = true; - - if (folding) { - if (CHAR_SPACE === character || CHAR_TAB === character) { - result += common.repeat('\n', emptyLines + 1); - emptyLines = 1; - } else if (0 === emptyLines) { - result += ' '; - emptyLines = 0; - } else { - result += common.repeat('\n', emptyLines); - emptyLines = 0; - } - } else { - result += common.repeat('\n', emptyLines + 1); - emptyLines = 0; - } - - captureStart = position; - - do { character = input.charCodeAt(++position); } - while (position < length && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character); - - captureSegment(captureStart, position, false); - } - - return true; - } - - function readBlockSequence(nodeIndent) { - var _line, - _tag = tag, - _result = [], - following, - detected = false; - - if (null !== anchor) { - anchorMap[anchor] = _result; - } - - while (position < length) { - if (CHAR_MINUS !== character) { - break; - } - - following = input.charCodeAt(position + 1); - - if (CHAR_SPACE !== following && - CHAR_TAB !== following && - CHAR_LINE_FEED !== following && - CHAR_CARRIAGE_RETURN !== following) { - break; - } - - detected = true; - position += 1; - character = following; - - if (skipSeparationSpace(true, -1)) { - if (lineIndent <= nodeIndent) { - _result.push(null); - continue; - } - } - - _line = line; - composeNode(nodeIndent, CONTEXT_BLOCK_IN, false, true); - _result.push(result); - skipSeparationSpace(true, -1); - - if ((line === _line || lineIndent > nodeIndent) && position < length) { - throwError('bad indentation of a sequence entry'); - } else if (lineIndent < nodeIndent) { - break; - } - } - - if (detected) { - tag = _tag; - kind = KIND_ARRAY; - result = _result; - return true; - } else { - return false; - } - } - - function readBlockMapping(nodeIndent) { - var following, - allowCompact, - _line, - _tag = tag, - _result = {}, - keyTag = null, - keyNode = null, - valueNode = null, - atExplicitKey = false, - detected = false; - - if (null !== anchor) { - anchorMap[anchor] = _result; - } - - while (position < length) { - following = input.charCodeAt(position + 1); - _line = line; // Save the current line. - - if ((CHAR_QUESTION === character || - CHAR_COLON === character) && - (CHAR_SPACE === following || - CHAR_TAB === following || - CHAR_LINE_FEED === following || - CHAR_CARRIAGE_RETURN === following)) { - - if (CHAR_QUESTION === character) { - if (atExplicitKey) { - storeMappingPair(_result, keyTag, keyNode, null); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = true; - allowCompact = true; - - } else if (atExplicitKey) { - // i.e. CHAR_COLON === character after the explicit key. - atExplicitKey = false; - allowCompact = true; - - } else { - throwError('incomplete explicit mapping pair; a key node is missed'); - } - - position += 1; - character = following; - - } else if (composeNode(nodeIndent, CONTEXT_FLOW_OUT, false, true)) { - if (line === _line) { - // TODO: Remove this cycle when the flow readers will consume - // trailing whitespaces like the block readers. - while (CHAR_SPACE === character || - CHAR_TAB === character) { - character = input.charCodeAt(++position); - } - - if (CHAR_COLON === character) { - character = input.charCodeAt(++position); - - if (CHAR_SPACE !== character && - CHAR_TAB !== character && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character) { - throwError('a whitespace character is expected after the key-value separator within a block mapping'); - } - - if (atExplicitKey) { - storeMappingPair(_result, keyTag, keyNode, null); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = false; - allowCompact = false; - keyTag = tag; - keyNode = result; - - } else if (detected) { - throwError('can not read an implicit mapping pair; a colon is missed'); - - } else { - tag = _tag; - return true; // Keep the result of `composeNode`. - } - - } else if (detected) { - throwError('can not read a block mapping entry; a multiline key may not be an implicit key'); - - } else { - tag = _tag; - return true; // Keep the result of `composeNode`. - } - - } else { - break; - } - - if (line === _line || lineIndent > nodeIndent) { - if (composeNode(nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { - if (atExplicitKey) { - keyNode = result; - } else { - valueNode = result; - } - } - - if (!atExplicitKey) { - storeMappingPair(_result, keyTag, keyNode, valueNode); - keyTag = keyNode = valueNode = null; - } - - // TODO: It is needed only for flow node readers. It should be removed - // when the flow readers will consume trailing whitespaces as well as - // the block readers. - skipSeparationSpace(true, -1); - } - - if (lineIndent > nodeIndent && position < length) { - throwError('bad indentation of a mapping entry'); - } else if (lineIndent < nodeIndent) { - break; - } - } - - if (atExplicitKey) { - storeMappingPair(_result, keyTag, keyNode, null); - } - - if (detected) { - tag = _tag; - kind = KIND_OBJECT; - result = _result; - } - - return detected; - } - - function readTagProperty() { - var _position, - isVerbatim = false, - isNamed = false, - tagHandle, - tagName; - - if (CHAR_EXCLAMATION !== character) { - return false; - } - - if (null !== tag) { - throwError('duplication of a tag property'); - } - - character = input.charCodeAt(++position); - - if (CHAR_LESS_THAN === character) { - isVerbatim = true; - character = input.charCodeAt(++position); - - } else if (CHAR_EXCLAMATION === character) { - isNamed = true; - tagHandle = '!!'; - character = input.charCodeAt(++position); - - } else { - tagHandle = '!'; - } - - _position = position; - - if (isVerbatim) { - do { character = input.charCodeAt(++position); } - while (position < length && CHAR_GREATER_THAN !== character); - - if (position < length) { - tagName = input.slice(_position, position); - character = input.charCodeAt(++position); - } else { - throwError('unexpected end of the stream within a verbatim tag'); - } - } else { - while (position < length && - CHAR_SPACE !== character && - CHAR_TAB !== character && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character) { - - if (CHAR_EXCLAMATION === character) { - if (!isNamed) { - tagHandle = input.slice(_position - 1, position + 1); - - if (validate && !PATTERN_TAG_HANDLE.test(tagHandle)) { - throwError('named tag handle cannot contain such characters'); - } - - isNamed = true; - _position = position + 1; - } else { - throwError('tag suffix cannot contain exclamation marks'); - } - } - - character = input.charCodeAt(++position); - } - - tagName = input.slice(_position, position); - - if (validate && PATTERN_FLOW_INDICATORS.test(tagName)) { - throwError('tag suffix cannot contain flow indicator characters'); - } - } - - if (validate && tagName && !PATTERN_TAG_URI.test(tagName)) { - throwError('tag name cannot contain such characters: ' + tagName); - } - - if (isVerbatim) { - tag = tagName; - - } else if (_hasOwnProperty.call(tagMap, tagHandle)) { - tag = tagMap[tagHandle] + tagName; - - } else if ('!' === tagHandle) { - tag = '!' + tagName; - - } else if ('!!' === tagHandle) { - tag = 'tag:yaml.org,2002:' + tagName; - - } else { - throwError('undeclared tag handle "' + tagHandle + '"'); - } - - return true; - } - - function readAnchorProperty() { - var _position; - - if (CHAR_AMPERSAND !== character) { - return false; - } - - if (null !== anchor) { - throwError('duplication of an anchor property'); - } - - character = input.charCodeAt(++position); - _position = position; - - while (position < length && - CHAR_SPACE !== character && - CHAR_TAB !== character && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character && - CHAR_COMMA !== character && - CHAR_LEFT_SQUARE_BRACKET !== character && - CHAR_RIGHT_SQUARE_BRACKET !== character && - CHAR_LEFT_CURLY_BRACKET !== character && - CHAR_RIGHT_CURLY_BRACKET !== character) { - character = input.charCodeAt(++position); - } - - if (position === _position) { - throwError('name of an anchor node must contain at least one character'); - } - - anchor = input.slice(_position, position); - return true; - } - - function readAlias() { - var _position, alias; - - if (CHAR_ASTERISK !== character) { - return false; - } - - character = input.charCodeAt(++position); - _position = position; - - while (position < length && - CHAR_SPACE !== character && - CHAR_TAB !== character && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character && - CHAR_COMMA !== character && - CHAR_LEFT_SQUARE_BRACKET !== character && - CHAR_RIGHT_SQUARE_BRACKET !== character && - CHAR_LEFT_CURLY_BRACKET !== character && - CHAR_RIGHT_CURLY_BRACKET !== character) { - character = input.charCodeAt(++position); - } - - if (position === _position) { - throwError('name of an alias node must contain at least one character'); - } - - alias = input.slice(_position, position); - - if (!anchorMap.hasOwnProperty(alias)) { - throwError('unidentified alias "' + alias + '"'); - } - - result = anchorMap[alias]; - skipSeparationSpace(true, -1); - return true; - } - - function composeNode(parentIndent, nodeContext, allowToSeek, allowCompact) { - var allowBlockStyles, - allowBlockScalars, - allowBlockCollections, - atNewLine = false, - isIndented = true, - hasContent = false, - typeIndex, - typeQuantity, - type, - typeLoader, - flowIndent, - blockIndent, - _result; - - tag = null; - anchor = null; - kind = null; - result = null; - - allowBlockStyles = allowBlockScalars = allowBlockCollections = - CONTEXT_BLOCK_OUT === nodeContext || - CONTEXT_BLOCK_IN === nodeContext; - - if (allowToSeek) { - if (skipSeparationSpace(true, -1)) { - atNewLine = true; - - if (lineIndent === parentIndent) { - isIndented = false; - - } else if (lineIndent > parentIndent) { - isIndented = true; - - } else { - return false; - } - } - } - - if (isIndented) { - while (readTagProperty() || readAnchorProperty()) { - if (skipSeparationSpace(true, -1)) { - atNewLine = true; - - if (lineIndent > parentIndent) { - isIndented = true; - allowBlockCollections = allowBlockStyles; - - } else if (lineIndent === parentIndent) { - isIndented = false; - allowBlockCollections = allowBlockStyles; - - } else { - return true; - } - } else { - allowBlockCollections = false; - } - } - } - - if (allowBlockCollections) { - allowBlockCollections = atNewLine || allowCompact; - } - - if (isIndented || CONTEXT_BLOCK_OUT === nodeContext) { - if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { - flowIndent = parentIndent; - } else { - flowIndent = parentIndent + 1; - } - - blockIndent = position - lineStart; - - if (isIndented) { - if (allowBlockCollections && - (readBlockSequence(blockIndent) || - readBlockMapping(blockIndent)) || - readFlowCollection(flowIndent)) { - hasContent = true; - } else { - if ((allowBlockScalars && readBlockScalar(flowIndent)) || - readSingleQuotedScalar(flowIndent) || - readDoubleQuotedScalar(flowIndent)) { - hasContent = true; - - } else if (readAlias()) { - hasContent = true; - - if (null !== tag || null !== anchor) { - throwError('alias node should not have any properties'); - } - - } else if (readPlainScalar(flowIndent, CONTEXT_FLOW_IN === nodeContext)) { - hasContent = true; - - if (null === tag) { - tag = '?'; - } - } - - if (null !== anchor) { - anchorMap[anchor] = result; - } - } - } else { - hasContent = allowBlockCollections && readBlockSequence(blockIndent); - } - } - - if (null !== tag && '!' !== tag) { - if ('?' === tag) { - if (resolve) { - for (typeIndex = 0, typeQuantity = implicitTypes.length; - typeIndex < typeQuantity; - typeIndex += 1) { - type = implicitTypes[typeIndex]; - - // Implicit resolving is not allowed for non-scalar types, and '?' - // non-specific tag is only assigned to plain scalars. So, it isn't - // needed to check for 'kind' conformity. - _result = type.loader.resolver(result, false); - - if (NIL !== _result) { - tag = type.tag; - result = _result; - break; - } - } - } - } else if (_hasOwnProperty.call(typeMap, tag)) { - typeLoader = typeMap[tag].loader; - - if (null !== result && typeLoader.kind !== kind) { - throwError('unacceptable node kind for !<' + tag + '> tag; it should be "' + typeLoader.kind + '", not "' + kind + '"'); - } - - if (typeLoader.resolver) { - _result = typeLoader.resolver(result, true); - - if (NIL !== _result) { - result = _result; - } else { - throwError('cannot resolve a node with !<' + tag + '> explicit tag'); - } - } - } else { - throwWarning('unknown tag !<' + tag + '>'); - } - } - - return null !== tag || null !== anchor || hasContent; - } - - function readDocument() { - var documentStart = position, - _position, - directiveName, - directiveArgs, - hasDirectives = false; - - version = null; - checkLineBreaks = legacy; - tagMap = {}; - anchorMap = {}; - - while (position < length) { - skipSeparationSpace(true, -1); - - if (lineIndent > 0 || CHAR_PERCENT !== character) { - break; - } - - hasDirectives = true; - character = input.charCodeAt(++position); - _position = position; - - while (position < length && - CHAR_SPACE !== character && - CHAR_TAB !== character && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character) { - character = input.charCodeAt(++position); - } - - directiveName = input.slice(_position, position); - directiveArgs = []; - - if (directiveName.length < 1) { - throwError('directive name must not be less than one character in length'); - } - - while (position < length) { - while (CHAR_SPACE === character || CHAR_TAB === character) { - character = input.charCodeAt(++position); - } - - if (CHAR_SHARP === character) { - do { character = input.charCodeAt(++position); } - while (position < length && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character); - break; - } - - if (CHAR_LINE_FEED === character || CHAR_CARRIAGE_RETURN === character) { - break; - } - - _position = position; - - while (position < length && - CHAR_SPACE !== character && - CHAR_TAB !== character && - CHAR_LINE_FEED !== character && - CHAR_CARRIAGE_RETURN !== character) { - character = input.charCodeAt(++position); - } - - directiveArgs.push(input.slice(_position, position)); - } - - if (position < length) { - readLineBreak(); - } - - if (_hasOwnProperty.call(directiveHandlers, directiveName)) { - directiveHandlers[directiveName](directiveName, directiveArgs); - } else { - throwWarning('unknown document directive "' + directiveName + '"'); - } - } - - skipSeparationSpace(true, -1); - - if (0 === lineIndent && - CHAR_MINUS === character && - CHAR_MINUS === input.charCodeAt(position + 1) && - CHAR_MINUS === input.charCodeAt(position + 2)) { - position += 3; - character = input.charCodeAt(position); - skipSeparationSpace(true, -1); - - } else if (hasDirectives) { - throwError('directives end mark is expected'); - } - - composeNode(lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); - skipSeparationSpace(true, -1); - - if (validate && checkLineBreaks && - PATTERN_NON_ASCII_LINE_BREAKS.test(input.slice(documentStart, position))) { - throwWarning('non-ASCII line breaks are interpreted as content'); - } - - output(result); - - if (position === lineStart && testDocumentSeparator()) { - if (CHAR_DOT === character) { - position += 3; - character = input.charCodeAt(position); - skipSeparationSpace(true, -1); - } - return; - } - - if (position < length) { - throwError('end of the stream or a document separator is expected'); - } else { - return; - } - } - - if (validate && PATTERN_NON_PRINTABLE.test(input)) { - throwError('the stream contains non-printable characters'); - } - - while (CHAR_SPACE === character) { - lineIndent += 1; - character = input.charCodeAt(++position); - } - - while (position < length) { - readDocument(); - } -} - - -function load(input, options) { - var result = null, received = false; - - function callback(data) { - if (!received) { - result = data; - received = true; - } else { - throw new YAMLException('expected a single document in the stream, but found more'); - } - } - - loadAll(input, callback, options); - - return result; -} - - -function safeLoadAll(input, output, options) { - loadAll(input, output, common.extend({ schema: SAFE_SCHEMA }, options)); -} - - -function safeLoad(input, options) { - return load(input, common.extend({ schema: SAFE_SCHEMA }, options)); -} - - -module.exports.loadAll = loadAll; -module.exports.load = load; -module.exports.safeLoadAll = safeLoadAll; -module.exports.safeLoad = safeLoad; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/mark.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/mark.js deleted file mode 100644 index bfe279ba..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/mark.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict'; - - -var common = require('./common'); - - -function Mark(name, buffer, position, line, column) { - this.name = name; - this.buffer = buffer; - this.position = position; - this.line = line; - this.column = column; -} - - -Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { - var head, start, tail, end, snippet; - - if (!this.buffer) { - return null; - } - - indent = indent || 4; - maxLength = maxLength || 75; - - head = ''; - start = this.position; - - while (start > 0 && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1))) { - start -= 1; - if (this.position - start > (maxLength / 2 - 1)) { - head = ' ... '; - start += 5; - break; - } - } - - tail = ''; - end = this.position; - - while (end < this.buffer.length && -1 === '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end))) { - end += 1; - if (end - this.position > (maxLength / 2 - 1)) { - tail = ' ... '; - end -= 5; - break; - } - } - - snippet = this.buffer.slice(start, end); - - return common.repeat(' ', indent) + head + snippet + tail + '\n' + - common.repeat(' ', indent + this.position - start + head.length) + '^'; -}; - - -Mark.prototype.toString = function toString(compact) { - var snippet, where = ''; - - if (this.name) { - where += 'in "' + this.name + '" '; - } - - where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); - - if (!compact) { - snippet = this.getSnippet(); - - if (snippet) { - where += ':\n' + snippet; - } - } - - return where; -}; - - -module.exports = Mark; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/require.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/require.js deleted file mode 100644 index 47b77e31..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/require.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - - -var fs = require('fs'); -var loader = require('./loader'); - - -function yamlRequireHandler(module, filename) { - var content = fs.readFileSync(filename, 'utf8'); - - // fill in documents - module.exports = loader.load(content, { filename: filename }); -} - -// register require extensions only if we're on node.js -// hack for browserify -if (undefined !== require.extensions) { - require.extensions['.yml'] = yamlRequireHandler; - require.extensions['.yaml'] = yamlRequireHandler; -} - - -module.exports = require; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema.js deleted file mode 100644 index ce213912..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema.js +++ /dev/null @@ -1,103 +0,0 @@ -'use strict'; - - -var common = require('./common'); -var YAMLException = require('./exception'); -var Type = require('./type'); - - -function compileList(schema, name, result) { - var exclude = []; - - schema.include.forEach(function (includedSchema) { - result = compileList(includedSchema, name, result); - }); - - schema[name].forEach(function (currentType) { - result.forEach(function (previousType, previousIndex) { - if (previousType.tag === currentType.tag) { - exclude.push(previousIndex); - } - }); - - result.push(currentType); - }); - - return result.filter(function (type, index) { - return -1 === exclude.indexOf(index); - }); -} - - -function compileMap(/* lists... */) { - var result = {}, index, length; - - function collectType(type) { - result[type.tag] = type; - } - - for (index = 0, length = arguments.length; index < length; index += 1) { - arguments[index].forEach(collectType); - } - - return result; -} - - -function Schema(definition) { - this.include = definition.include || []; - this.implicit = definition.implicit || []; - this.explicit = definition.explicit || []; - - this.implicit.forEach(function (type) { - if (null !== type.loader && 'string' !== type.loader.kind) { - throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); - } - }); - - this.compiledImplicit = compileList(this, 'implicit', []); - this.compiledExplicit = compileList(this, 'explicit', []); - this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); -} - - -Schema.DEFAULT = null; - - -Schema.create = function createSchema() { - var schemas, types; - - switch (arguments.length) { - case 1: - schemas = Schema.DEFAULT; - types = arguments[0]; - break; - - case 2: - schemas = arguments[0]; - types = arguments[1]; - break; - - default: - throw new YAMLException('Wrong number of arguments for Schema.create function'); - } - - schemas = common.toArray(schemas); - types = common.toArray(types); - - if (!schemas.every(function (schema) { return schema instanceof Schema; })) { - throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); - } - - if (!types.every(function (type) { return type instanceof Type; })) { - throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - - return new Schema({ - include: schemas, - explicit: types - }); -}; - - -module.exports = Schema; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/default.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/default.js deleted file mode 100644 index 71bb3fcc..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/default.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - - -var Schema = require('../schema'); - - -module.exports = Schema.DEFAULT = new Schema({ - include: [ - require('./safe') - ], - explicit: [ - require('../type/js/undefined'), - require('../type/js/regexp'), - require('../type/js/function') - ] -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/minimal.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/minimal.js deleted file mode 100644 index 7a6ebbec..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/minimal.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - - -var Schema = require('../schema'); - - -module.exports = new Schema({ - explicit: [ - require('../type/str'), - require('../type/seq'), - require('../type/map') - ] -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/safe.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/safe.js deleted file mode 100644 index 856b7c41..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/schema/safe.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - - -var Schema = require('../schema'); - - -module.exports = new Schema({ - include: [ - require('./minimal') - ], - implicit: [ - require('../type/null'), - require('../type/bool'), - require('../type/int'), - require('../type/float'), - require('../type/timestamp'), - require('../type/merge') - ], - explicit: [ - require('../type/binary'), - require('../type/omap'), - require('../type/pairs'), - require('../type/set') - ] -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type.js deleted file mode 100644 index e0124f2c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type.js +++ /dev/null @@ -1,82 +0,0 @@ -'use strict'; - - -var YAMLException = require('./exception'); - - -// TODO: Add tag format check. -function Type(tag, options) { - options = options || {}; - - this.tag = tag; - this.loader = options['loader'] || null; - this.dumper = options['dumper'] || null; - - if (null === this.loader && null === this.dumper) { - throw new YAMLException('Incomplete YAML type definition. "loader" or "dumper" setting must be specified.'); - } - - if (null !== this.loader) { - this.loader = new Type.Loader(this.loader); - } - - if (null !== this.dumper) { - this.dumper = new Type.Dumper(this.dumper); - } -} - - -Type.Loader = function TypeLoader(options) { - options = options || {}; - - this.kind = options['kind'] || null; - this.resolver = options['resolver'] || null; - - if ('string' !== this.kind && - 'array' !== this.kind && - 'object' !== this.kind) { - throw new YAMLException('Unacceptable "kind" setting of a type loader.'); - } -}; - - -function compileAliases(map) { - var result = {}; - - if (null !== map) { - Object.keys(map).forEach(function (style) { - map[style].forEach(function (alias) { - result[String(alias)] = style; - }); - }); - } - - return result; -} - - -Type.Dumper = function TypeDumper(options) { - options = options || {}; - - this.kind = options['kind'] || null; - this.defaultStyle = options['defaultStyle'] || null; - this.instanceOf = options['instanceOf'] || null; - this.predicate = options['predicate'] || null; - this.representer = options['representer'] || null; - this.styleAliases = compileAliases(options['styleAliases'] || null); - - if ('undefined' !== this.kind && - 'null' !== this.kind && - 'boolean' !== this.kind && - 'integer' !== this.kind && - 'float' !== this.kind && - 'string' !== this.kind && - 'array' !== this.kind && - 'object' !== this.kind && - 'function' !== this.kind) { - throw new YAMLException('Unacceptable "kind" setting of a type dumper.'); - } -}; - - -module.exports = Type; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/binary.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/binary.js deleted file mode 100644 index 37b4bc70..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/binary.js +++ /dev/null @@ -1,118 +0,0 @@ -// Modified from: -// https://raw.github.com/kanaka/noVNC/d890e8640f20fba3215ba7be8e0ff145aeb8c17c/include/base64.js - -'use strict'; - - -var NodeBuffer = require('buffer').Buffer; // A trick for browserified version. -var common = require('../common'); -var NIL = common.NIL; -var Type = require('../type'); - - - -var BASE64_PADDING = '='; - -var BASE64_BINTABLE = [ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 -]; - -var BASE64_CHARTABLE = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); - - -function resolveYamlBinary(object /*, explicit*/) { - var value, code, idx = 0, result = [], leftbits, leftdata; - - leftbits = 0; // number of bits decoded, but yet to be appended - leftdata = 0; // bits decoded, but yet to be appended - - // Convert one by one. - for (idx = 0; idx < object.length; idx += 1) { - code = object.charCodeAt(idx); - value = BASE64_BINTABLE[code & 0x7F]; - - // Skip LF(NL) || CR - if (0x0A !== code && 0x0D !== code) { - // Fail on illegal characters - if (-1 === value) { - return NIL; - } - - // Collect data into leftdata, update bitcount - leftdata = (leftdata << 6) | value; - leftbits += 6; - - // If we have 8 or more bits, append 8 bits to the result - if (leftbits >= 8) { - leftbits -= 8; - - // Append if not padding. - if (BASE64_PADDING !== object.charAt(idx)) { - result.push((leftdata >> leftbits) & 0xFF); - } - - leftdata &= (1 << leftbits) - 1; - } - } - } - - // If there are any bits left, the base64 string was corrupted - if (leftbits) { - return NIL; - } else { - return new NodeBuffer(result); - } -} - - -function representYamlBinary(object /*, style*/) { - var result = '', index, length, rest; - - // Convert every three bytes to 4 ASCII characters. - for (index = 0, length = object.length - 2; index < length; index += 3) { - result += BASE64_CHARTABLE[object[index + 0] >> 2]; - result += BASE64_CHARTABLE[((object[index + 0] & 0x03) << 4) + (object[index + 1] >> 4)]; - result += BASE64_CHARTABLE[((object[index + 1] & 0x0F) << 2) + (object[index + 2] >> 6)]; - result += BASE64_CHARTABLE[object[index + 2] & 0x3F]; - } - - rest = object.length % 3; - - // Convert the remaining 1 or 2 bytes, padding out to 4 characters. - if (0 !== rest) { - index = object.length - rest; - result += BASE64_CHARTABLE[object[index + 0] >> 2]; - - if (2 === rest) { - result += BASE64_CHARTABLE[((object[index + 0] & 0x03) << 4) + (object[index + 1] >> 4)]; - result += BASE64_CHARTABLE[(object[index + 1] & 0x0F) << 2]; - result += BASE64_PADDING; - } else { - result += BASE64_CHARTABLE[(object[index + 0] & 0x03) << 4]; - result += BASE64_PADDING + BASE64_PADDING; - } - } - - return result; -} - - -module.exports = new Type('tag:yaml.org,2002:binary', { - loader: { - kind: 'string', - resolver: resolveYamlBinary - }, - dumper: { - kind: 'object', - instanceOf: NodeBuffer, - representer: representYamlBinary - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/bool.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/bool.js deleted file mode 100644 index 987a9e62..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/bool.js +++ /dev/null @@ -1,74 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var YAML_IMPLICIT_BOOLEAN_MAP = { - 'true' : true, - 'True' : true, - 'TRUE' : true, - 'false' : false, - 'False' : false, - 'FALSE' : false -}; - -var YAML_EXPLICIT_BOOLEAN_MAP = { - 'true' : true, - 'True' : true, - 'TRUE' : true, - 'false' : false, - 'False' : false, - 'FALSE' : false, - 'y' : true, - 'Y' : true, - 'yes' : true, - 'Yes' : true, - 'YES' : true, - 'n' : false, - 'N' : false, - 'no' : false, - 'No' : false, - 'NO' : false, - 'on' : true, - 'On' : true, - 'ON' : true, - 'off' : false, - 'Off' : false, - 'OFF' : false -}; - - -function resolveYamlBoolean(object, explicit) { - if (explicit) { - if (YAML_EXPLICIT_BOOLEAN_MAP.hasOwnProperty(object)) { - return YAML_EXPLICIT_BOOLEAN_MAP[object]; - } else { - return NIL; - } - } else { - if (YAML_IMPLICIT_BOOLEAN_MAP.hasOwnProperty(object)) { - return YAML_IMPLICIT_BOOLEAN_MAP[object]; - } else { - return NIL; - } - } -} - - -module.exports = new Type('tag:yaml.org,2002:bool', { - loader: { - kind: 'string', - resolver: resolveYamlBoolean - }, - dumper: { - kind: 'boolean', - defaultStyle: 'lowercase', - representer: { - lowercase: function (object) { return object ? 'true' : 'false'; }, - uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, - camelcase: function (object) { return object ? 'True' : 'False'; } - } - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/float.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/float.js deleted file mode 100644 index edb5fcba..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/float.js +++ /dev/null @@ -1,102 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var YAML_FLOAT_PATTERN = new RegExp( - '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + - '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + - '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + - '|[-+]?\\.(?:inf|Inf|INF)' + - '|\\.(?:nan|NaN|NAN))$'); - - -function resolveYamlFloat(object /*, explicit*/) { - var value, sign, base, digits; - - if (!YAML_FLOAT_PATTERN.test(object)) { - return NIL; - } - - value = object.replace(/_/g, '').toLowerCase(); - sign = '-' === value[0] ? -1 : 1; - digits = []; - - if (0 <= '+-'.indexOf(value[0])) { - value = value.slice(1); - } - - if ('.inf' === value) { - return (1 === sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; - - } else if ('.nan' === value) { - return NaN; - - } else if (0 <= value.indexOf(':')) { - value.split(':').forEach(function (v) { - digits.unshift(parseFloat(v, 10)); - }); - - value = 0.0; - base = 1; - - digits.forEach(function (d) { - value += d * base; - base *= 60; - }); - - return sign * value; - - } else { - return sign * parseFloat(value, 10); - } -} - - -function representYamlFloat(object, style) { - if (isNaN(object)) { - switch (style) { - case 'lowercase': - return '.nan'; - case 'uppercase': - return '.NAN'; - case 'camelcase': - return '.NaN'; - } - } else if (Number.POSITIVE_INFINITY === object) { - switch (style) { - case 'lowercase': - return '.inf'; - case 'uppercase': - return '.INF'; - case 'camelcase': - return '.Inf'; - } - } else if (Number.NEGATIVE_INFINITY === object) { - switch (style) { - case 'lowercase': - return '-.inf'; - case 'uppercase': - return '-.INF'; - case 'camelcase': - return '-.Inf'; - } - } else { - return object.toString(10); - } -} - - -module.exports = new Type('tag:yaml.org,2002:float', { - loader: { - kind: 'string', - resolver: resolveYamlFloat - }, - dumper: { - kind: 'float', - defaultStyle: 'lowercase', - representer: representYamlFloat - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/int.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/int.js deleted file mode 100644 index f5e1e7e5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/int.js +++ /dev/null @@ -1,85 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var YAML_INTEGER_PATTERN = new RegExp( - '^(?:[-+]?0b[0-1_]+' + - '|[-+]?0[0-7_]+' + - '|[-+]?(?:0|[1-9][0-9_]*)' + - '|[-+]?0x[0-9a-fA-F_]+' + - '|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$'); - - -function resolveYamlInteger(object /*, explicit*/) { - var value, sign, base, digits; - - if (!YAML_INTEGER_PATTERN.test(object)) { - return NIL; - } - - value = object.replace(/_/g, ''); - sign = '-' === value[0] ? -1 : 1; - digits = []; - - if (0 <= '+-'.indexOf(value[0])) { - value = value.slice(1); - } - - if ('0' === value) { - return 0; - - } else if (/^0b/.test(value)) { - return sign * parseInt(value.slice(2), 2); - - } else if (/^0x/.test(value)) { - return sign * parseInt(value, 16); - - } else if ('0' === value[0]) { - return sign * parseInt(value, 8); - - } else if (0 <= value.indexOf(':')) { - value.split(':').forEach(function (v) { - digits.unshift(parseInt(v, 10)); - }); - - value = 0; - base = 1; - - digits.forEach(function (d) { - value += (d * base); - base *= 60; - }); - - return sign * value; - - } else { - return sign * parseInt(value, 10); - } -} - - -module.exports = new Type('tag:yaml.org,2002:int', { - loader: { - kind: 'string', - resolver: resolveYamlInteger - }, - dumper: { - kind: 'integer', - defaultStyle: 'decimal', - representer: { - binary: function (object) { return '0b' + object.toString(2); }, - octal: function (object) { return '0' + object.toString(8); }, - decimal: function (object) { return object.toString(10); }, - hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } - }, - styleAliases: { - binary: [ 2, 'bin' ], - octal: [ 8, 'oct' ], - decimal: [ 10, 'dec' ], - hexadecimal: [ 16, 'hex' ] - } - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/function.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/function.js deleted file mode 100644 index 4b3b3ca5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/function.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict'; - - -var esprima = require('esprima'); - - -var NIL = require('../../common').NIL; -var Type = require('../../type'); - - -function resolveJavascriptFunction(object /*, explicit*/) { - /*jslint evil:true*/ - - try { - var source = '(' + object + ')', - ast = esprima.parse(source, { range: true }), - params = [], - body; - - if ('Program' !== ast.type || - 1 !== ast.body.length || - 'ExpressionStatement' !== ast.body[0].type || - 'FunctionExpression' !== ast.body[0].expression.type) { - return NIL; - } - - ast.body[0].expression.params.forEach(function (param) { - params.push(param.name); - }); - - body = ast.body[0].expression.body.range; - - // Esprima's ranges include the first '{' and the last '}' characters on - // function expressions. So cut them out. - return new Function(params, source.slice(body[0]+1, body[1]-1)); - } catch (err) { - return NIL; - } -} - - -function representJavascriptFunction(object /*, style*/) { - return object.toString(); -} - - -module.exports = new Type('tag:yaml.org,2002:js/function', { - loader: { - kind: 'string', - resolver: resolveJavascriptFunction - }, - dumper: { - kind: 'function', - representer: representJavascriptFunction, - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js deleted file mode 100644 index 9f4f89e0..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict'; - - -var NIL = require('../../common').NIL; -var Type = require('../../type'); - - -function resolveJavascriptRegExp(object /*, explicit*/) { - var regexp = object, - tail = /\/([gim]*)$/.exec(object), - modifiers; - - // `/foo/gim` - tail can be maximum 4 chars - if ('/' === regexp[0] && tail && 4 >= tail[0].length) { - regexp = regexp.slice(1, regexp.length - tail[0].length); - modifiers = tail[1]; - } - - try { - return new RegExp(regexp, modifiers); - } catch (error) { - return NIL; - } -} - - -function representJavascriptRegExp(object /*, style*/) { - var result = '/' + object.source + '/'; - - if (object.global) { - result += 'g'; - } - - if (object.multiline) { - result += 'm'; - } - - if (object.ignoreCase) { - result += 'i'; - } - - return result; -} - - -module.exports = new Type('tag:yaml.org,2002:js/regexp', { - loader: { - kind: 'string', - resolver: resolveJavascriptRegExp - }, - dumper: { - kind: 'object', - instanceOf: RegExp, - representer: representJavascriptRegExp - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js deleted file mode 100644 index 8d2835e1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - - -var Type = require('../../type'); - - -function resolveJavascriptUndefined(/*object, explicit*/) { - var undef; - - return undef; -} - - -function representJavascriptUndefined(/*object, explicit*/) { - return ''; -} - - -module.exports = new Type('tag:yaml.org,2002:js/undefined', { - loader: { - kind: 'string', - resolver: resolveJavascriptUndefined - }, - dumper: { - kind: 'undefined', - representer: representJavascriptUndefined - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/map.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/map.js deleted file mode 100644 index 5cda6de7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/map.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - - -var Type = require('../type'); - - -module.exports = new Type('tag:yaml.org,2002:map', { - loader: { - kind: 'object' - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/merge.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/merge.js deleted file mode 100644 index 8facc708..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/merge.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -function resolveYamlMerge(object /*, explicit*/) { - return '<<' === object ? object : NIL; -} - - -module.exports = new Type('tag:yaml.org,2002:merge', { - loader: { - kind: 'string', - resolver: resolveYamlMerge - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/null.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/null.js deleted file mode 100644 index 796e1af1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/null.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var YAML_NULL_MAP = { - '~' : true, - 'null' : true, - 'Null' : true, - 'NULL' : true -}; - - -function resolveYamlNull(object /*, explicit*/) { - return YAML_NULL_MAP[object] ? null : NIL; -} - - -module.exports = new Type('tag:yaml.org,2002:null', { - loader: { - kind: 'string', - resolver: resolveYamlNull - }, - dumper: { - kind: 'null', - defaultStyle: 'lowercase', - representer: { - canonical: function () { return '~'; }, - lowercase: function () { return 'null'; }, - uppercase: function () { return 'NULL'; }, - camelcase: function () { return 'Null'; }, - } - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/omap.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/omap.js deleted file mode 100644 index f7c248d4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/omap.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var _hasOwnProperty = Object.prototype.hasOwnProperty; -var _toString = Object.prototype.toString; - - -function resolveYamlOmap(object /*, explicit*/) { - var objectKeys = [], index, length, pair, pairKey, pairHasKey; - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - pairHasKey = false; - - if ('[object Object]' !== _toString.call(pair)) { - return NIL; - } - - for (pairKey in pair) { - if (_hasOwnProperty.call(pair, pairKey)) { - if (!pairHasKey) { - pairHasKey = true; - } else { - return NIL; - } - } - } - - if (!pairHasKey) { - return NIL; - } - - if (-1 === objectKeys.indexOf(pairKey)) { - objectKeys.push(pairKey); - } else { - return NIL; - } - } - - return object; -} - - -module.exports = new Type('tag:yaml.org,2002:omap', { - loader: { - kind: 'array', - resolver: resolveYamlOmap - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/pairs.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/pairs.js deleted file mode 100644 index 828ff1bb..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/pairs.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var _toString = Object.prototype.toString; - - -function resolveYamlPairs(object /*, explicit*/) { - var index, length, pair, keys, result; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - if ('[object Object]' !== _toString.call(pair)) { - return NIL; - } - - keys = Object.keys(pair); - - if (1 !== keys.length) { - return NIL; - } - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return result; -} - - -module.exports = new Type('tag:yaml.org,2002:pairs', { - loader: { - kind: 'array', - resolver: resolveYamlPairs - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/seq.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/seq.js deleted file mode 100644 index 80a7cf0f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/seq.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - - -var Type = require('../type'); - - -module.exports = new Type('tag:yaml.org,2002:seq', { - loader: { - kind: 'array' - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/set.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/set.js deleted file mode 100644 index 64bdc669..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/set.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var _hasOwnProperty = Object.prototype.hasOwnProperty; - - -function resolveYamlSet(object /*, explicit*/) { - var key; - - for (key in object) { - if (_hasOwnProperty.call(object, key)) { - if (null !== object[key]) { - return NIL; - } - } - } - - return object; -} - - -module.exports = new Type('tag:yaml.org,2002:set', { - loader: { - kind: 'object', - resolver: resolveYamlSet - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/str.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/str.js deleted file mode 100644 index 384f14e4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/str.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - - -var Type = require('../type'); - - -module.exports = new Type('tag:yaml.org,2002:str', { - loader: { - kind: 'string' - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/timestamp.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/timestamp.js deleted file mode 100644 index 24da9e2e..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +++ /dev/null @@ -1,91 +0,0 @@ -'use strict'; - - -var NIL = require('../common').NIL; -var Type = require('../type'); - - -var YAML_TIMESTAMP_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9]?)' + // [2] month - '-([0-9][0-9]?)' + // [3] day - '(?:(?:[Tt]|[ \\t]+)' + // ... - '([0-9][0-9]?)' + // [4] hour - ':([0-9][0-9])' + // [5] minute - ':([0-9][0-9])' + // [6] second - '(?:\\.([0-9]*))?' + // [7] fraction - '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour - '(?::([0-9][0-9]))?))?)?$'); // [11] tz_minute - - -function resolveYamlTimestamp(object /*, explicit*/) { - var match, year, month, day, hour, minute, second, fraction = 0, - delta = null, tz_hour, tz_minute, data; - - match = YAML_TIMESTAMP_REGEXP.exec(object); - - if (null === match) { - return NIL; - } - - // match: [1] year [2] month [3] day - - year = +(match[1]); - month = +(match[2]) - 1; // JS month starts with 0 - day = +(match[3]); - - if (!match[4]) { // no hour - return new Date(Date.UTC(year, month, day)); - } - - // match: [4] hour [5] minute [6] second [7] fraction - - hour = +(match[4]); - minute = +(match[5]); - second = +(match[6]); - - if (match[7]) { - fraction = match[7].slice(0, 3); - while (fraction.length < 3) { // milli-seconds - fraction += '0'; - } - fraction = +fraction; - } - - // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute - - if (match[9]) { - tz_hour = +(match[10]); - tz_minute = +(match[11] || 0); - delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds - if ('-' === match[9]) { - delta = -delta; - } - } - - data = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); - - if (delta) { - data.setTime(data.getTime() - delta); - } - - return data; -} - - -function representYamlTimestamp(object /*, style*/) { - return object.toISOString(); -} - - -module.exports = new Type('tag:yaml.org,2002:timestamp', { - loader: { - kind: 'string', - resolver: resolveYamlTimestamp - }, - dumper: { - kind: 'object', - instanceOf: Date, - representer: representYamlTimestamp - } -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esparse b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esparse deleted file mode 120000 index 7423b18b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esparse +++ /dev/null @@ -1 +0,0 @@ -../esprima/bin/esparse.js \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esvalidate b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esvalidate deleted file mode 120000 index 16069eff..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/.bin/esvalidate +++ /dev/null @@ -1 +0,0 @@ -../esprima/bin/esvalidate.js \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/HISTORY.md b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/HISTORY.md deleted file mode 100644 index 102f82bf..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/HISTORY.md +++ /dev/null @@ -1,109 +0,0 @@ -0.1.15 / 2013-05-13 -------------------- - -* Fixed #55, @trebor89 - - -0.1.14 / 2013-05-12 -------------------- - -* Fixed #62, @maxtaco - - -0.1.13 / 2013-04-08 -------------------- - -* Added `.npmignore` to reduce package size - - -0.1.12 / 2013-02-10 -------------------- - -* Fixed conflictHandler (#46), @hpaulj - - -0.1.11 / 2013-02-07 -------------------- - -* Multiple bugfixes, @hpaulj -* Added 70+ tests (ported from python), @hpaulj -* Added conflictHandler, @applepicke -* Added fromfilePrefixChar, @hpaulj - - -0.1.10 / 2012-12-30 -------------------- - -* Added [mutual exclusion](http://docs.python.org/dev/library/argparse.html#mutual-exclusion) - support, thanks to @hpaulj -* Fixed options check for `storeConst` & `appendConst` actions, thanks to @hpaulj - - -0.1.9 / 2012-12-27 ------------------- - -* Fixed option dest interferens with other options (issue #23), thanks to @hpaulj -* Fixed default value behavior with `*` positionals, thanks to @hpaulj -* Improve `getDefault()` behavior, thanks to @hpaulj -* Imrove negative argument parsing, thanks to @hpaulj - - -0.1.8 / 2012-12-01 ------------------- - -* Fixed parser parents (issue #19), thanks to @hpaulj -* Fixed negative argument parse (issue #20), thanks to @hpaulj - - -0.1.7 / 2012-10-14 ------------------- - -* Fixed 'choices' argument parse (issue #16) -* Fixed stderr output (issue #15) - - -0.1.6 / 2012-09-09 ------------------- - -* Fixed check for conflict of options (thanks to @tomxtobin) - - -0.1.5 / 2012-09-03 ------------------- - -* Fix parser #setDefaults method (thanks to @tomxtobin) - - -0.1.4 / 2012-07-30 ------------------- - -* Fixed pseudo-argument support (thanks to @CGamesPlay) -* Fixed addHelp default (should be true), if not set (thanks to @benblank) - - -0.1.3 / 2012-06-27 ------------------- - -* Fixed formatter api name: Formatter -> HelpFormatter - - -0.1.2 / 2012-05-29 ------------------- - -* Added basic tests -* Removed excess whitespace in help -* Fixed error reporting, when parcer with subcommands - called with empty arguments - - -0.1.1 / 2012-05-23 ------------------- - -* Fixed line wrapping in help formatter -* Added better error reporting on invalid arguments - - -0.1.0 / 2012-05-16 ------------------- - -* First release. diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/LICENSE b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/LICENSE deleted file mode 100644 index 1afdae55..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -(The MIT License) - -Copyright (C) 2012 by Vitaly Puzrin - -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/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/README.md b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/README.md deleted file mode 100644 index f20e0c1f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/README.md +++ /dev/null @@ -1,239 +0,0 @@ -argparse -======== - -[![Build Status](https://secure.travis-ci.org/nodeca/argparse.png?branch=master)](http://travis-ci.org/nodeca/argparse) - -CLI arguments parser for node.js. Javascript port of python's -[argparse](http://docs.python.org/dev/library/argparse.html) module -(original version 3.2). That's a full port, except some very rare options, -recorded in issue tracker. - -**NB.** Method names changed to camelCase. See [generated docs](http://nodeca.github.com/argparse/). - - -Example -======= - -test.js file: - -```javascript -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp:true, - description: 'Argparse example' -}); -parser.addArgument( - [ '-f', '--foo' ], - { - help: 'foo bar' - } -); -parser.addArgument( - [ '-b', '--bar' ], - { - help: 'bar foo' - } -); -var args = parser.parseArgs(); -console.dir(args); -``` - -Display help: - -``` -$ ./test.js -h -usage: example.js [-h] [-v] [-f FOO] [-b BAR] - -Argparse example - -Optional arguments: - -h, --help Show this help message and exit. - -v, --version Show program's version number and exit. - -f FOO, --foo FOO foo bar - -b BAR, --bar BAR bar foo -``` - -Parse arguments: - -``` -$ ./test.js -f=3 --bar=4 -{ foo: '3', bar: '4' } -``` - -More [examples](https://github.com/nodeca/argparse/tree/master/examples). - - -ArgumentParser objects -====================== - -``` -new ArgumentParser({paramters hash}); -``` - -Creates a new ArgumentParser object. - -**Supported params:** - -- ```description``` - Text to display before the argument help. -- ```epilog``` - Text to display after the argument help. -- ```addHelp``` - Add a -h/–help option to the parser. (default: True) -- ```argumentDefault``` - Set the global default value for arguments. (default: None) -- ```parents``` - A list of ArgumentParser objects whose arguments should also be included. -- ```prefixChars``` - The set of characters that prefix optional arguments. (default: ‘-‘) -- ```formatterClass``` - A class for customizing the help output. -- ```prog``` - The name of the program (default: sys.argv[0]) -- ```usage``` - The string describing the program usage (default: generated) -- ```conflictHandler``` - Usually unnecessary, defines strategy for resolving conflicting optionals. - -**Not supportied yet** - -- ```fromfilePrefixChars``` - The set of characters that prefix files from which additional arguments should be read. - - -Details in [original ArgumentParser guide](http://docs.python.org/dev/library/argparse.html#argumentparser-objects) - - -addArgument() method -==================== - -``` -ArgumentParser.addArgument([names or flags], {options}) -``` - -Defines how a single command-line argument should be parsed. - -- ```name or flags``` - Either a name or a list of option strings, e.g. foo or -f, --foo. - -Options: - -- ```action``` - The basic type of action to be taken when this argument is encountered at the command line. -- ```nargs```- The number of command-line arguments that should be consumed. -- ```constant``` - A constant value required by some action and nargs selections. -- ```defaultValue``` - The value produced if the argument is absent from the command line. -- ```type``` - The type to which the command-line argument should be converted. -- ```choices``` - A container of the allowable values for the argument. -- ```required``` - Whether or not the command-line option may be omitted (optionals only). -- ```help``` - A brief description of what the argument does. -- ```metavar``` - A name for the argument in usage messages. -- ```dest``` - The name of the attribute to be added to the object returned by parseArgs(). - -Details in [original add_argument guide](http://docs.python.org/dev/library/argparse.html#the-add-argument-method) - - -Action (some details) -================ - -ArgumentParser objects associate command-line arguments with actions. -These actions can do just about anything with the command-line arguments associated -with them, though most actions simply add an attribute to the object returned by -parseArgs(). The action keyword argument specifies how the command-line arguments -should be handled. The supported actions are: - -- ```store``` - Just stores the argument’s value. This is the default action. -- ```storeConst``` - Stores value, specified by the const keyword argument. - (Note that the const keyword argument defaults to the rather unhelpful None.) - The 'storeConst' action is most commonly used with optional arguments, that - specify some sort of flag. -- ```storeTrue``` and ```storeFalse``` - Stores values True and False - respectively. These are special cases of 'storeConst'. -- ```append``` - Stores a list, and appends each argument value to the list. - This is useful to allow an option to be specified multiple times. -- ```appendConst``` - Stores a list, and appends value, specified by the - const keyword argument to the list. (Note, that the const keyword argument defaults - is None.) The 'appendConst' action is typically used when multiple arguments need - to store constants to the same list. -- ```count``` - Counts the number of times a keyword argument occurs. For example, - used for increasing verbosity levels. -- ```help``` - Prints a complete help message for all the options in the current - parser and then exits. By default a help action is automatically added to the parser. - See ArgumentParser for details of how the output is created. -- ```version``` - Prints version information and exit. Expects a `version=` - keyword argument in the addArgument() call. - -Details in [original action guide](http://docs.python.org/dev/library/argparse.html#action) - - -Sub-commands -============ - -ArgumentParser.addSubparsers() - -Many programs split their functionality into a number of sub-commands, for -example, the svn program can invoke sub-commands like `svn checkout`, `svn update`, -and `svn commit`. Splitting up functionality this way can be a particularly good -idea when a program performs several different functions which require different -kinds of command-line arguments. `ArgumentParser` supports creation of such -sub-commands with `addSubparsers()` method. The `addSubparsers()` method is -normally called with no arguments and returns an special action object. -This object has a single method `addParser()`, which takes a command name and -any `ArgumentParser` constructor arguments, and returns an `ArgumentParser` object -that can be modified as usual. - -Example: - -sub_commands.js -```javascript -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp:true, - description: 'Argparse examples: sub-commands', -}); - -var subparsers = parser.addSubparsers({ - title:'subcommands', - dest:"subcommand_name" -}); - -var bar = subparsers.addParser('c1', {addHelp:true}); -bar.addArgument( - [ '-f', '--foo' ], - { - action: 'store', - help: 'foo3 bar3' - } -); -var bar = subparsers.addParser( - 'c2', - {aliases:['co'], addHelp:true} -); -bar.addArgument( - [ '-b', '--bar' ], - { - action: 'store', - type: 'int', - help: 'foo3 bar3' - } -); - -var args = parser.parseArgs(); -console.dir(args); - -``` - -Details in [original sub-commands guide](http://docs.python.org/dev/library/argparse.html#sub-commands) - - -Contributors -============ - -- [Eugene Shkuropat](https://github.com/shkuropat) -- [Paul Jacobson](https://github.com/hpaulj) - -[others](https://github.com/nodeca/argparse/graphs/contributors) - -License -======= - -Copyright (c) 2012 [Vitaly Puzrin](https://github.com/puzrin). -Released under the MIT license. See -[LICENSE](https://github.com/nodeca/argparse/blob/master/LICENSE) for details. - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/arguments.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/arguments.js deleted file mode 100755 index 5b090fa2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/arguments.js +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: arguments' -}); -parser.addArgument( - [ '-f', '--foo' ], - { - help: 'foo bar' - } -); -parser.addArgument( - [ '-b', '--bar' ], - { - help: 'bar foo' - } -); - - -parser.printHelp(); -console.log('-----------'); - -var args; -args = parser.parseArgs('-f 1 -b2'.split(' ')); -console.dir(args); -console.log('-----------'); -args = parser.parseArgs('-f=3 --bar=4'.split(' ')); -console.dir(args); -console.log('-----------'); -args = parser.parseArgs('--foo 5 --bar 6'.split(' ')); -console.dir(args); -console.log('-----------'); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/choice.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/choice.js deleted file mode 100755 index 2616fa4d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/choice.js +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: choice' -}); - -parser.addArgument(['foo'], {choices: 'abc'}); - -parser.printHelp(); -console.log('-----------'); - -var args; -args = parser.parseArgs(['c']); -console.dir(args); -console.log('-----------'); -parser.parseArgs(['X']); -console.dir(args); - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/constants.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/constants.js deleted file mode 100755 index 172a4f3d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/constants.js +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: constant' -}); - -parser.addArgument( - [ '-a'], - { - action: 'storeConst', - dest: 'answer', - help: 'store constant', - constant: 42 - } -); -parser.addArgument( - [ '--str' ], - { - action: 'appendConst', - dest: 'types', - help: 'append constant "str" to types', - constant: 'str' - } -); -parser.addArgument( - [ '--int' ], - { - action: 'appendConst', - dest: 'types', - help: 'append constant "int" to types', - constant: 'int' - } -); - -parser.addArgument( - [ '--true' ], - { - action: 'storeTrue', - help: 'store true constant' - } -); -parser.addArgument( - [ '--false' ], - { - action: 'storeFalse', - help: 'store false constant' - } -); - -parser.printHelp(); -console.log('-----------'); - -var args; -args = parser.parseArgs('-a --str --int --true'.split(' ')); -console.dir(args); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/help.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/help.js deleted file mode 100755 index 7eb95553..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/help.js +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: help', - epilog: 'help epilog', - prog: 'help_example_prog', - usage: 'Usage %(prog)s ' -}); -parser.printHelp(); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/nargs.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/nargs.js deleted file mode 100755 index 74f376be..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/nargs.js +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: nargs' -}); -parser.addArgument( - [ '-f', '--foo' ], - { - help: 'foo bar', - nargs: 1 - } -); -parser.addArgument( - [ '-b', '--bar' ], - { - help: 'bar foo', - nargs: '*' - } -); - -parser.printHelp(); -console.log('-----------'); - -var args; -args = parser.parseArgs('--foo a --bar c d'.split(' ')); -console.dir(args); -console.log('-----------'); -args = parser.parseArgs('--bar b c f --foo a'.split(' ')); -console.dir(args); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/parents.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/parents.js deleted file mode 100755 index dfe89686..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/parents.js +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; - -var args; -var parent_parser = new ArgumentParser({ addHelp: false }); -// note addHelp:false to prevent duplication of the -h option -parent_parser.addArgument( - ['--parent'], - { type: 'int', description: 'parent' } -); - -var foo_parser = new ArgumentParser({ - parents: [ parent_parser ], - description: 'child1' -}); -foo_parser.addArgument(['foo']); -args = foo_parser.parseArgs(['--parent', '2', 'XXX']); -console.log(args); - -var bar_parser = new ArgumentParser({ - parents: [ parent_parser ], - description: 'child2' -}); -bar_parser.addArgument(['--bar']); -args = bar_parser.parseArgs(['--bar', 'YYY']); -console.log(args); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/prefix_chars.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/prefix_chars.js deleted file mode 100755 index 430d5e18..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/prefix_chars.js +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: prefix_chars', - prefixChars: '-+' -}); -parser.addArgument(['+f', '++foo']); -parser.addArgument(['++bar'], {action: 'storeTrue'}); - -parser.printHelp(); -console.log('-----------'); - -var args; -args = parser.parseArgs(['+f', '1']); -console.dir(args); -args = parser.parseArgs(['++bar']); -console.dir(args); -args = parser.parseArgs(['++foo', '2', '++bar']); -console.dir(args); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sub_commands.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sub_commands.js deleted file mode 100755 index df9c4944..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sub_commands.js +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ - version: '0.0.1', - addHelp: true, - description: 'Argparse examples: sub-commands' -}); - -var subparsers = parser.addSubparsers({ - title: 'subcommands', - dest: "subcommand_name" -}); - -var bar = subparsers.addParser('c1', {addHelp: true, help: 'c1 help'}); -bar.addArgument( - [ '-f', '--foo' ], - { - action: 'store', - help: 'foo3 bar3' - } -); -var bar = subparsers.addParser( - 'c2', - {aliases: ['co'], addHelp: true, help: 'c2 help'} -); -bar.addArgument( - [ '-b', '--bar' ], - { - action: 'store', - type: 'int', - help: 'foo3 bar3' - } -); -parser.printHelp(); -console.log('-----------'); - -var args; -args = parser.parseArgs('c1 -f 2'.split(' ')); -console.dir(args); -console.log('-----------'); -args = parser.parseArgs('c2 -b 1'.split(' ')); -console.dir(args); -console.log('-----------'); -args = parser.parseArgs('co -b 1'.split(' ')); -console.dir(args); -console.log('-----------'); -parser.parseArgs(['c1', '-h']); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sum.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sum.js deleted file mode 100755 index 4532800a..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/sum.js +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env node - -'use strict'; - - -var ArgumentParser = require('../lib/argparse').ArgumentParser; -var parser = new ArgumentParser({ description: 'Process some integers.' }); - - -function sum(arr) { - return arr.reduce(function (a, b) { - return a + b; - }, 0); -} -function max(arr) { - return Math.max.apply(Math, arr); -} - - -parser.addArgument(['integers'], { - metavar: 'N', - type: 'int', - nargs: '+', - help: 'an integer for the accumulator' -}); -parser.addArgument(['--sum'], { - dest: 'accumulate', - action: 'storeConst', - constant: sum, - defaultValue: max, - help: 'sum the integers (default: find the max)' -}); - -var args = parser.parseArgs('--sum 1 2 -1'.split(' ')); -console.log(args.accumulate(args.integers)); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/testformatters.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/testformatters.js deleted file mode 100644 index afb4a2d6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/examples/testformatters.js +++ /dev/null @@ -1,270 +0,0 @@ -'use strict'; - -var a, group, parser, helptext; - -var assert = require('assert'); -var _ = require('underscore'); -_.str = require('underscore.string'); -var print = function () { - return console.log.apply(console, arguments); - }; -// print = function () {}; - -var argparse = require('argparse'); - -print("TEST argparse.ArgumentDefaultsHelpFormatter"); - -parser = new argparse.ArgumentParser({ - debug: true, - formatterClass: argparse.ArgumentDefaultsHelpFormatter, - description: 'description' -}); - -parser.addArgument(['--foo'], { - help: 'foo help - oh and by the way, %(defaultValue)s' -}); - -parser.addArgument(['--bar'], { - action: 'storeTrue', - help: 'bar help' -}); - -parser.addArgument(['spam'], { - help: 'spam help' -}); - -parser.addArgument(['badger'], { - nargs: '?', - defaultValue: 'wooden', - help: 'badger help' -}); - -group = parser.addArgumentGroup({ - title: 'title', - description: 'group description' -}); - -group.addArgument(['--baz'], { - type: 'int', - defaultValue: 42, - help: 'baz help' -}); - -helptext = parser.formatHelp(); -print(helptext); -// test selected clips -assert(helptext.match(/badger help \(default: wooden\)/)); -assert(helptext.match(/foo help - oh and by the way, null/)); -assert(helptext.match(/bar help \(default: false\)/)); -assert(helptext.match(/title:\n {2}group description/)); // test indent -assert(helptext.match(/baz help \(default: 42\)/im)); - -/* -usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger] - -description - -positional arguments: - spam spam help - badger badger help (default: wooden) - -optional arguments: - -h, --help show this help message and exit - --foo FOO foo help - oh and by the way, null - --bar bar help (default: false) - -title: - group description - - --baz BAZ baz help (default: 42) -*/ - -print("TEST argparse.RawDescriptionHelpFormatter"); - -parser = new argparse.ArgumentParser({ - debug: true, - prog: 'PROG', - formatterClass: argparse.RawDescriptionHelpFormatter, - description: 'Keep the formatting\n' + - ' exactly as it is written\n' + - '\n' + - 'here\n' -}); - -a = parser.addArgument(['--foo'], { - help: ' foo help should not\n' + - ' retain this odd formatting' -}); - -parser.addArgument(['spam'], { - 'help': 'spam help' -}); - -group = parser.addArgumentGroup({ - title: 'title', - description: ' This text\n' + - ' should be indented\n' + - ' exactly like it is here\n' -}); - -group.addArgument(['--bar'], { - help: 'bar help' -}); - -helptext = parser.formatHelp(); -print(helptext); -// test selected clips -assert(helptext.match(parser.description)); -assert.equal(helptext.match(a.help), null); -assert(helptext.match(/foo help should not retain this odd formatting/)); - -/* -class TestHelpRawDescription(HelpTestCase): - """Test the RawTextHelpFormatter""" -.... - -usage: PROG [-h] [--foo FOO] [--bar BAR] spam - -Keep the formatting - exactly as it is written - -here - -positional arguments: - spam spam help - -optional arguments: - -h, --help show this help message and exit - --foo FOO foo help should not retain this odd formatting - -title: - This text - should be indented - exactly like it is here - - --bar BAR bar help -*/ - - -print("TEST argparse.RawTextHelpFormatter"); - -parser = new argparse.ArgumentParser({ - debug: true, - prog: 'PROG', - formatterClass: argparse.RawTextHelpFormatter, - description: 'Keep the formatting\n' + - ' exactly as it is written\n' + - '\n' + - 'here\n' -}); - -parser.addArgument(['--baz'], { - help: ' baz help should also\n' + - 'appear as given here' -}); - -a = parser.addArgument(['--foo'], { - help: ' foo help should also\n' + - 'appear as given here' -}); - -parser.addArgument(['spam'], { - 'help': 'spam help' -}); - -group = parser.addArgumentGroup({ - title: 'title', - description: ' This text\n' + - ' should be indented\n' + - ' exactly like it is here\n' -}); - -group.addArgument(['--bar'], { - help: 'bar help' -}); - -helptext = parser.formatHelp(); -print(helptext); -// test selected clips -assert(helptext.match(parser.description)); -assert(helptext.match(/( {14})appear as given here/gm)); - -/* -class TestHelpRawText(HelpTestCase): - """Test the RawTextHelpFormatter""" - -usage: PROG [-h] [--foo FOO] [--bar BAR] spam - -Keep the formatting - exactly as it is written - -here - -positional arguments: - spam spam help - -optional arguments: - -h, --help show this help message and exit - --foo FOO foo help should also - appear as given here - -title: - This text - should be indented - exactly like it is here - - --bar BAR bar help -*/ - - -print("TEST metavar as a tuple"); - -parser = new argparse.ArgumentParser({ - prog: 'PROG' -}); - -parser.addArgument(['-w'], { - help: 'w', - nargs: '+', - metavar: ['W1', 'W2'] -}); - -parser.addArgument(['-x'], { - help: 'x', - nargs: '*', - metavar: ['X1', 'X2'] -}); - -parser.addArgument(['-y'], { - help: 'y', - nargs: 3, - metavar: ['Y1', 'Y2', 'Y3'] -}); - -parser.addArgument(['-z'], { - help: 'z', - nargs: '?', - metavar: ['Z1'] -}); - -helptext = parser.formatHelp(); -print(helptext); -var ustring = 'PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] [-z [Z1]]'; -ustring = ustring.replace(/\[/g, '\\[').replace(/\]/g, '\\]'); -// print(ustring) -assert(helptext.match(new RegExp(ustring))); - -/* -class TestHelpTupleMetavar(HelpTestCase): - """Test specifying metavar as a tuple""" - -usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] [-z [Z1]] - -optional arguments: - -h, --help show this help message and exit - -w W1 [W2 ...] w - -x [X1 [X2 ...]] x - -y Y1 Y2 Y3 y - -z [Z1] z -*/ - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/index.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/index.js deleted file mode 100644 index 3b6eea01..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./lib/argparse'); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action.js deleted file mode 100644 index 6f7e9a56..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * class Action - * - * Base class for all actions - * Do not call in your code, use this class only for inherits your own action - * - * Information about how to convert command line strings to Javascript objects. - * Action objects are used by an ArgumentParser to represent the information - * needed to parse a single argument from one or more strings from the command - * line. The keyword arguments to the Action constructor are also all attributes - * of Action instances. - * - * #####Alowed keywords: - * - * - `store` - * - `storeConstant` - * - `storeTrue` - * - `storeFalse` - * - `append` - * - `appendConstant` - * - `count` - * - `help` - * - `version` - * - * Information about action options see [[Action.new]] - * - * See also [original guide](http://docs.python.org/dev/library/argparse.html#action) - * - **/ - -'use strict'; - - -// Constants -var $$ = require('./const'); - - -/** - * new Action(options) - * - * Base class for all actions. Used only for inherits - * - * - * ##### Options: - * - * - `optionStrings` A list of command-line option strings for the action. - * - `dest` Attribute to hold the created object(s) - * - `nargs` The number of command-line arguments that should be consumed. - * By default, one argument will be consumed and a single value will be - * produced. - * - `constant` Default value for an action with no value. - * - `defaultValue` The value to be produced if the option is not specified. - * - `type` Cast to 'string'|'int'|'float'|'complex'|function (string). If - * None, 'string'. - * - `choices` The choices available. - * - `required` True if the action must always be specified at the command - * line. - * - `help` The help describing the argument. - * - `metavar` The name to be used for the option's argument with the help - * string. If None, the 'dest' value will be used as the name. - * - * ##### nargs supported values: - * - * - `N` (an integer) consumes N arguments (and produces a list) - * - `?` consumes zero or one arguments - * - `*` consumes zero or more arguments (and produces a list) - * - `+` consumes one or more arguments (and produces a list) - * - * Note: that the difference between the default and nargs=1 is that with the - * default, a single value will be produced, while with nargs=1, a list - * containing a single value will be produced. - **/ -var Action = module.exports = function Action(options) { - options = options || {}; - this.optionStrings = options.optionStrings || []; - this.dest = options.dest; - this.nargs = options.nargs !== undefined ? options.nargs : null; - this.constant = options.constant !== undefined ? options.constant : null; - this.defaultValue = options.defaultValue; - this.type = options.type !== undefined ? options.type : null; - this.choices = options.choices !== undefined ? options.choices : null; - this.required = options.required !== undefined ? options.required: false; - this.help = options.help !== undefined ? options.help : null; - this.metavar = options.metavar !== undefined ? options.metavar : null; - - if (!(this.optionStrings instanceof Array)) { - throw new Error('optionStrings should be an array'); - } - if (this.required !== undefined && typeof(this.required) !== 'boolean') { - throw new Error('required should be a boolean'); - } -}; - -/** - * Action#getName -> String - * - * Tells action name - **/ -Action.prototype.getName = function () { - if (this.optionStrings.length > 0) { - return this.optionStrings.join('/'); - } else if (this.metavar !== null && this.metavar !== $$.SUPPRESS) { - return this.metavar; - } else if (this.dest !== undefined && this.dest !== $$.SUPPRESS) { - return this.dest; - } - return null; -}; - -/** - * Action#isOptional -> Boolean - * - * Return true if optional - **/ -Action.prototype.isOptional = function () { - return !this.isPositional(); -}; - -/** - * Action#isPositional -> Boolean - * - * Return true if positional - **/ -Action.prototype.isPositional = function () { - return (this.optionStrings.length === 0); -}; - -/** - * Action#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Should be implemented in inherited classes - * - * ##### Example - * - * ActionCount.prototype.call = function (parser, namespace, values, optionString) { - * namespace.set(this.dest, (namespace[this.dest] || 0) + 1); - * }; - * - **/ -Action.prototype.call = function () { - throw new Error('.call() not defined');// Not Implemented error -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append.js deleted file mode 100644 index 48c6dbe3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append.js +++ /dev/null @@ -1,55 +0,0 @@ -/*:nodoc:* - * class ActionAppend - * - * This action stores a list, and appends each argument value to the list. - * This is useful to allow an option to be specified multiple times. - * This class inherided from [[Action]] - * - **/ - -'use strict'; - -var util = require('util'); - -var Action = require('../action'); - -// Constants -var $$ = require('../const'); - -/*:nodoc:* - * new ActionAppend(options) - * - options (object): options hash see [[Action.new]] - * - * Note: options.nargs should be optional for constants - * and more then zero for other - **/ -var ActionAppend = module.exports = function ActionAppend(options) { - options = options || {}; - if (this.nargs <= 0) { - throw new Error('nargs for append actions must be > 0; if arg ' + - 'strings are not supplying the value to append, ' + - 'the append const action may be more appropriate'); - } - if (!!this.constant && this.nargs !== $$.OPTIONAL) { - throw new Error('nargs must be OPTIONAL to supply const'); - } - Action.call(this, options); -}; -util.inherits(ActionAppend, Action); - -/*:nodoc:* - * ActionAppend#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Save result in namespace object - **/ -ActionAppend.prototype.call = function (parser, namespace, values) { - var items = [].concat(namespace[this.dest] || []); // or _.clone - items.push(values); - namespace.set(this.dest, items); -}; - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append/constant.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append/constant.js deleted file mode 100644 index 90747abb..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/append/constant.js +++ /dev/null @@ -1,47 +0,0 @@ -/*:nodoc:* - * class ActionAppendConstant - * - * This stores a list, and appends the value specified by - * the const keyword argument to the list. - * (Note that the const keyword argument defaults to null.) - * The 'appendConst' action is typically useful when multiple - * arguments need to store constants to the same list. - * - * This class inherited from [[Action]] - **/ - -'use strict'; - -var util = require('util'); - -var Action = require('../../action'); - -/*:nodoc:* - * new ActionAppendConstant(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionAppendConstant = module.exports = function ActionAppendConstant(options) { - options = options || {}; - options.nargs = 0; - if (options.constant === undefined) { - throw new Error('constant option is required for appendAction'); - } - Action.call(this, options); -}; -util.inherits(ActionAppendConstant, Action); - -/*:nodoc:* - * ActionAppendConstant#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Save result in namespace object - **/ -ActionAppendConstant.prototype.call = function (parser, namespace) { - var items = [].concat(namespace[this.dest] || []); - items.push(this.constant); - namespace.set(this.dest, items); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/count.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/count.js deleted file mode 100644 index d6a5899d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/count.js +++ /dev/null @@ -1,40 +0,0 @@ -/*:nodoc:* - * class ActionCount - * - * This counts the number of times a keyword argument occurs. - * For example, this is useful for increasing verbosity levels - * - * This class inherided from [[Action]] - * - **/ -'use strict'; - -var util = require('util'); - -var Action = require('../action'); - -/*:nodoc:* - * new ActionCount(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionCount = module.exports = function ActionCount(options) { - options = options || {}; - options.nargs = 0; - - Action.call(this, options); -}; -util.inherits(ActionCount, Action); - -/*:nodoc:* - * ActionCount#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Save result in namespace object - **/ -ActionCount.prototype.call = function (parser, namespace) { - namespace.set(this.dest, (namespace[this.dest] || 0) + 1); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/help.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/help.js deleted file mode 100644 index 7f7b4e2d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/help.js +++ /dev/null @@ -1,48 +0,0 @@ -/*:nodoc:* - * class ActionHelp - * - * Support action for printing help - * This class inherided from [[Action]] - **/ -'use strict'; - -var util = require('util'); - -var Action = require('../action'); - -// Constants -var $$ = require('../const'); - -/*:nodoc:* - * new ActionHelp(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionHelp = module.exports = function ActionHelp(options) { - options = options || {}; - if (options.defaultValue !== null) { - options.defaultValue = options.defaultValue; - } - else { - options.defaultValue = $$.SUPPRESS; - } - options.dest = (options.dest !== null ? options.dest: $$.SUPPRESS); - options.nargs = 0; - Action.call(this, options); - -}; -util.inherits(ActionHelp, Action); - -/*:nodoc:* - * ActionHelp#call(parser, namespace, values, optionString) - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Print help and exit - **/ -ActionHelp.prototype.call = function (parser) { - parser.printHelp(); - parser.exit(); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store.js deleted file mode 100644 index 8ebc9748..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store.js +++ /dev/null @@ -1,50 +0,0 @@ -/*:nodoc:* - * class ActionStore - * - * This action just stores the argument’s value. This is the default action. - * - * This class inherited from [[Action]] - * - **/ -'use strict'; - -var util = require('util'); - -var Action = require('../action'); - -// Constants -var $$ = require('../const'); - - -/*:nodoc:* - * new ActionStore(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionStore = module.exports = function ActionStore(options) { - options = options || {}; - if (this.nargs <= 0) { - throw new Error('nargs for store actions must be > 0; if you ' + - 'have nothing to store, actions such as store ' + - 'true or store const may be more appropriate'); - - } - if (this.constant !== undefined && this.nargs !== $$.OPTIONAL) { - throw new Error('nargs must be OPTIONAL to supply const'); - } - Action.call(this, options); -}; -util.inherits(ActionStore, Action); - -/*:nodoc:* - * ActionStore#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Save result in namespace object - **/ -ActionStore.prototype.call = function (parser, namespace, values) { - namespace.set(this.dest, values); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/constant.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/constant.js deleted file mode 100644 index 8410fcf7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/constant.js +++ /dev/null @@ -1,43 +0,0 @@ -/*:nodoc:* - * class ActionStoreConstant - * - * This action stores the value specified by the const keyword argument. - * (Note that the const keyword argument defaults to the rather unhelpful null.) - * The 'store_const' action is most commonly used with optional - * arguments that specify some sort of flag. - * - * This class inherited from [[Action]] - **/ -'use strict'; - -var util = require('util'); - -var Action = require('../../action'); - -/*:nodoc:* - * new ActionStoreConstant(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionStoreConstant = module.exports = function ActionStoreConstant(options) { - options = options || {}; - options.nargs = 0; - if (options.constant === undefined) { - throw new Error('constant option is required for storeAction'); - } - Action.call(this, options); -}; -util.inherits(ActionStoreConstant, Action); - -/*:nodoc:* - * ActionStoreConstant#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Save result in namespace object - **/ -ActionStoreConstant.prototype.call = function (parser, namespace) { - namespace.set(this.dest, this.constant); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/false.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/false.js deleted file mode 100644 index 66417bf6..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/false.js +++ /dev/null @@ -1,27 +0,0 @@ -/*:nodoc:* - * class ActionStoreFalse - * - * This action store the values False respectively. - * This is special cases of 'storeConst' - * - * This class inherited from [[Action]] - **/ - -'use strict'; - -var util = require('util'); - -var ActionStoreConstant = require('./constant'); - -/*:nodoc:* - * new ActionStoreFalse(options) - * - options (object): hash of options see [[Action.new]] - * - **/ -var ActionStoreFalse = module.exports = function ActionStoreFalse(options) { - options = options || {}; - options.constant = false; - options.defaultValue = options.defaultValue !== null ? options.defaultValue: true; - ActionStoreConstant.call(this, options); -}; -util.inherits(ActionStoreFalse, ActionStoreConstant); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/true.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/true.js deleted file mode 100644 index 43ec7086..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/store/true.js +++ /dev/null @@ -1,26 +0,0 @@ -/*:nodoc:* - * class ActionStoreTrue - * - * This action store the values True respectively. - * This isspecial cases of 'storeConst' - * - * This class inherited from [[Action]] - **/ -'use strict'; - -var util = require('util'); - -var ActionStoreConstant = require('./constant'); - -/*:nodoc:* - * new ActionStoreTrue(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionStoreTrue = module.exports = function ActionStoreTrue(options) { - options = options || {}; - options.constant = true; - options.defaultValue = options.defaultValue !== null ? options.defaultValue: false; - ActionStoreConstant.call(this, options); -}; -util.inherits(ActionStoreTrue, ActionStoreConstant); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/subparsers.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/subparsers.js deleted file mode 100644 index adecf654..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/subparsers.js +++ /dev/null @@ -1,148 +0,0 @@ -/** internal - * class ActionSubparsers - * - * Support the creation of such sub-commands with the addSubparsers() - * - * This class inherited from [[Action]] - **/ -'use strict'; - -var util = require('util'); -var format = require('util').format; -var _ = require('underscore'); - - -var Action = require('../action'); - -// Constants -var $$ = require('../const'); - -// Errors -var argumentErrorHelper = require('../argument/error'); - - -/*:nodoc:* - * new ChoicesPseudoAction(name, help) - * - * Create pseudo action for correct help text - * - **/ -var ChoicesPseudoAction = function (name, help) { - var options = { - optionStrings: [], - dest: name, - help: help - }; - - Action.call(this, options); -}; -util.inherits(ChoicesPseudoAction, Action); - -/** - * new ActionSubparsers(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionSubparsers = module.exports = function ActionSubparsers(options) { - options = options || {}; - options.dest = options.dest || $$.SUPPRESS; - options.nargs = $$.PARSER; - - this.debug = (options.debug === true); - - this._progPrefix = options.prog; - this._parserClass = options.parserClass; - this._nameParserMap = {}; - this._choicesActions = []; - - options.choices = this._nameParserMap; - Action.call(this, options); -}; -util.inherits(ActionSubparsers, Action); - -/*:nodoc:* - * ActionSubparsers#addParser(name, options) -> ArgumentParser - * - name (string): sub-command name - * - options (object): see [[ArgumentParser.new]] - * - * Note: - * addParser supports an additional aliases option, - * which allows multiple strings to refer to the same subparser. - * This example, like svn, aliases co as a shorthand for checkout - * - **/ -ActionSubparsers.prototype.addParser = function (name, options) { - var parser; - - var self = this; - - options = options || {}; - - options.debug = (this.debug === true); - - // set program from the existing prefix - if (!options.prog) { - options.prog = this._progPrefix + ' ' + name; - } - - var aliases = options.aliases || []; - - // create a pseudo-action to hold the choice help - if (!!options.help || _.isString(options.help)) { - var help = options.help; - delete options.help; - - var choiceAction = new ChoicesPseudoAction(name, help); - this._choicesActions.push(choiceAction); - } - - // create the parser and add it to the map - parser = new this._parserClass(options); - this._nameParserMap[name] = parser; - - // make parser available under aliases also - aliases.forEach(function (alias) { - self._nameParserMap[alias] = parser; - }); - - return parser; -}; - -ActionSubparsers.prototype._getSubactions = function () { - return this._choicesActions; -}; - -/*:nodoc:* - * ActionSubparsers#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Call the action. Parse input aguments - **/ -ActionSubparsers.prototype.call = function (parser, namespace, values) { - var parserName = values[0]; - var argStrings = values.slice(1); - - // set the parser name if requested - if (this.dest !== $$.SUPPRESS) { - namespace[this.dest] = parserName; - } - - // select the parser - if (!!this._nameParserMap[parserName]) { - parser = this._nameParserMap[parserName]; - } else { - throw argumentErrorHelper(format( - 'Unknown parser "%s" (choices: [%s]).', - parserName, - _.keys(this._nameParserMap).join(', ') - )); - } - - // parse all the remaining options into the namespace - parser.parseArgs(argStrings, namespace); -}; - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/version.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/version.js deleted file mode 100644 index a17877c0..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action/version.js +++ /dev/null @@ -1,50 +0,0 @@ -/*:nodoc:* - * class ActionVersion - * - * Support action for printing program version - * This class inherited from [[Action]] - **/ -'use strict'; - -var util = require('util'); - -var Action = require('../action'); - -// -// Constants -// -var $$ = require('../const'); - -/*:nodoc:* - * new ActionVersion(options) - * - options (object): options hash see [[Action.new]] - * - **/ -var ActionVersion = module.exports = function ActionVersion(options) { - options = options || {}; - options.defaultValue = (!!options.defaultValue ? options.defaultValue: $$.SUPPRESS); - options.dest = (options.dest || $$.SUPPRESS); - options.nargs = 0; - this.version = options.version; - Action.call(this, options); -}; -util.inherits(ActionVersion, Action); - -/*:nodoc:* - * ActionVersion#call(parser, namespace, values, optionString) -> Void - * - parser (ArgumentParser): current parser - * - namespace (Namespace): namespace for output data - * - values (Array): parsed values - * - optionString (Array): input option string(not parsed) - * - * Print version and exit - **/ -ActionVersion.prototype.call = function (parser) { - var version = this.version || parser.version; - var formatter = parser._getFormatter(); - formatter.addText(version); - parser.exit(0, formatter.formatHelp()); -}; - - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action_container.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action_container.js deleted file mode 100644 index dbe3e3c4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/action_container.js +++ /dev/null @@ -1,481 +0,0 @@ -/** internal - * class ActionContainer - * - * Action container. Parent for [[ArgumentParser]] and [[ArgumentGroup]] - **/ - -'use strict'; - -var format = require('util').format; -var _ = require('underscore'); - -_.str = require('underscore.string'); - -// Constants -var $$ = require('./const'); - -//Actions -var ActionHelp = require('./action/help'); -var ActionAppend = require('./action/append'); -var ActionAppendConstant = require('./action/append/constant'); -var ActionCount = require('./action/count'); -var ActionStore = require('./action/store'); -var ActionStoreConstant = require('./action/store/constant'); -var ActionStoreTrue = require('./action/store/true'); -var ActionStoreFalse = require('./action/store/false'); -var ActionVersion = require('./action/version'); -var ActionSubparsers = require('./action/subparsers'); - -// Errors -var argumentErrorHelper = require('./argument/error'); - - - -/** - * new ActionContainer(options) - * - * Action container. Parent for [[ArgumentParser]] and [[ArgumentGroup]] - * - * ##### Options: - * - * - `description` -- A description of what the program does - * - `prefixChars` -- Characters that prefix optional arguments - * - `argumentDefault` -- The default value for all arguments - * - `conflictHandler` -- The conflict handler to use for duplicate arguments - **/ -var ActionContainer = module.exports = function ActionContainer(options) { - options = options || {}; - - this.description = options.description; - this.argumentDefault = options.argumentDefault; - this.prefixChars = options.prefixChars || ''; - this.conflictHandler = options.conflictHandler; - - // set up registries - this._registries = {}; - - // register actions - this.register('action', null, ActionStore); - this.register('action', 'store', ActionStore); - this.register('action', 'storeConst', ActionStoreConstant); - this.register('action', 'storeTrue', ActionStoreTrue); - this.register('action', 'storeFalse', ActionStoreFalse); - this.register('action', 'append', ActionAppend); - this.register('action', 'appendConst', ActionAppendConstant); - this.register('action', 'count', ActionCount); - this.register('action', 'help', ActionHelp); - this.register('action', 'version', ActionVersion); - this.register('action', 'parsers', ActionSubparsers); - - // raise an exception if the conflict handler is invalid - this._getHandler(); - - // action storage - this._actions = []; - this._optionStringActions = {}; - - // groups - this._actionGroups = []; - this._mutuallyExclusiveGroups = []; - - // defaults storage - this._defaults = {}; - - // determines whether an "option" looks like a negative number - // -1, -1.5 -5e+4 - this._regexpNegativeNumber = new RegExp('^[-]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$'); - - // whether or not there are any optionals that look like negative - // numbers -- uses a list so it can be shared and edited - this._hasNegativeNumberOptionals = []; -}; - -// Groups must be required, then ActionContainer already defined -var ArgumentGroup = require('./argument/group'); -var MutuallyExclusiveGroup = require('./argument/exclusive'); - -// -// Registration methods -// - -/** - * ActionContainer#register(registryName, value, object) -> Void - * - registryName (String) : object type action|type - * - value (string) : keyword - * - object (Object|Function) : handler - * - * Register handlers - **/ -ActionContainer.prototype.register = function (registryName, value, object) { - this._registries[registryName] = this._registries[registryName] || {}; - this._registries[registryName][value] = object; -}; - -ActionContainer.prototype._registryGet = function (registryName, value, defaultValue) { - if (3 > arguments.length) { - defaultValue = null; - } - return this._registries[registryName][value] || defaultValue; -}; - -// -// Namespace default accessor methods -// - -/** - * ActionContainer#setDefaults(options) -> Void - * - options (object):hash of options see [[Action.new]] - * - * Set defaults - **/ -ActionContainer.prototype.setDefaults = function (options) { - options = options || {}; - for (var property in options) { - this._defaults[property] = options[property]; - } - - // if these defaults match any existing arguments, replace the previous - // default on the object with the new one - this._actions.forEach(function (action) { - if (action.dest in options) { - action.defaultValue = options[action.dest]; - } - }); -}; - -/** - * ActionContainer#getDefault(dest) -> Mixed - * - dest (string): action destination - * - * Return action default value - **/ -ActionContainer.prototype.getDefault = function (dest) { - var result = (_.has(this._defaults, dest)) ? this._defaults[dest] : null; - - this._actions.forEach(function (action) { - if (action.dest === dest && _.has(action, 'defaultValue')) { - result = action.defaultValue; - } - }); - - return result; -}; -// -// Adding argument actions -// - -/** - * ActionContainer#addArgument(args, options) -> Object - * - args (Array): array of argument keys - * - options (Object): action objects see [[Action.new]] - * - * #### Examples - * - addArgument([-f, --foo], {action:'store', defaultValue=1, ...}) - * - addArgument(['bar'], action: 'store', nargs:1, ...}) - **/ -ActionContainer.prototype.addArgument = function (args, options) { - args = args; - options = options || {}; - - if (!_.isArray(args)) { - throw new TypeError('addArgument first argument should be an array'); - } - if (!_.isObject(options) || _.isArray(options)) { - throw new TypeError('addArgument second argument should be a hash'); - } - - // if no positional args are supplied or only one is supplied and - // it doesn't look like an option string, parse a positional argument - if (!args || args.length === 1 && this.prefixChars.indexOf(args[0][0]) < 0) { - if (args && !!options.dest) { - throw new Error('dest supplied twice for positional argument'); - } - options = this._getPositional(args, options); - - // otherwise, we're adding an optional argument - } else { - options = this._getOptional(args, options); - } - - // if no default was supplied, use the parser-level default - if (_.isUndefined(options.defaultValue)) { - var dest = options.dest; - if (_.has(this._defaults, dest)) { - options.defaultValue = this._defaults[dest]; - } else if (!_.isUndefined(this.argumentDefault)) { - options.defaultValue = this.argumentDefault; - } - } - - // create the action object, and add it to the parser - var ActionClass = this._popActionClass(options); - if (! _.isFunction(ActionClass)) { - throw new Error(format('Unknown action "%s".', ActionClass)); - } - var action = new ActionClass(options); - - // throw an error if the action type is not callable - var typeFunction = this._registryGet('type', action.type, action.type); - if (!_.isFunction(typeFunction)) { - throw new Error(format('"%s" is not callable', typeFunction)); - } - - return this._addAction(action); -}; - -/** - * ActionContainer#addArgumentGroup(options) -> ArgumentGroup - * - options (Object): hash of options see [[ArgumentGroup.new]] - * - * Create new arguments groups - **/ -ActionContainer.prototype.addArgumentGroup = function (options) { - var group = new ArgumentGroup(this, options); - this._actionGroups.push(group); - return group; -}; - -/** - * ActionContainer#addMutuallyExclusiveGroup(options) -> ArgumentGroup - * - options (Object): {required: false} - * - * Create new mutual exclusive groups - **/ -ActionContainer.prototype.addMutuallyExclusiveGroup = function (options) { - var group = new MutuallyExclusiveGroup(this, options); - this._mutuallyExclusiveGroups.push(group); - return group; -}; - -ActionContainer.prototype._addAction = function (action) { - var self = this; - - // resolve any conflicts - this._checkConflict(action); - - // add to actions list - this._actions.push(action); - action.container = this; - - // index the action by any option strings it has - action.optionStrings.forEach(function (optionString) { - self._optionStringActions[optionString] = action; - }); - - // set the flag if any option strings look like negative numbers - action.optionStrings.forEach(function (optionString) { - if (optionString.match(self._regexpNegativeNumber)) { - if (!_.any(self._hasNegativeNumberOptionals)) { - self._hasNegativeNumberOptionals.push(true); - } - } - }); - - // return the created action - return action; -}; - -ActionContainer.prototype._removeAction = function (action) { - var actionIndex = this._actions.indexOf(action); - if (actionIndex >= 0) { - this._actions.splice(actionIndex, 1); - } -}; - -ActionContainer.prototype._addContainerActions = function (container) { - // collect groups by titles - var titleGroupMap = {}; - this._actionGroups.forEach(function (group) { - if (titleGroupMap[group.title]) { - throw new Error(format('Cannot merge actions - two groups are named "%s".', group.title)); - } - titleGroupMap[group.title] = group; - }); - - // map each action to its group - var groupMap = {}; - function actionHash(action) { - // unique (hopefully?) string suitable as dictionary key - return action.getName(); - } - container._actionGroups.forEach(function (group) { - // if a group with the title exists, use that, otherwise - // create a new group matching the container's group - if (!titleGroupMap[group.title]) { - titleGroupMap[group.title] = this.addArgumentGroup({ - title: group.title, - description: group.description - }); - } - - // map the actions to their new group - group._groupActions.forEach(function (action) { - groupMap[actionHash(action)] = titleGroupMap[group.title]; - }); - }, this); - - // add container's mutually exclusive groups - // NOTE: if add_mutually_exclusive_group ever gains title= and - // description= then this code will need to be expanded as above - var mutexGroup; - container._mutuallyExclusiveGroups.forEach(function (group) { - mutexGroup = this.addMutuallyExclusiveGroup({ - required: group.required - }); - // map the actions to their new mutex group - group._groupActions.forEach(function (action) { - groupMap[actionHash(action)] = mutexGroup; - }); - }, this); // forEach takes a 'this' argument - - // add all actions to this container or their group - container._actions.forEach(function (action) { - var key = actionHash(action); - if (!!groupMap[key]) { - groupMap[key]._addAction(action); - } - else - { - this._addAction(action); - } - }); -}; - -ActionContainer.prototype._getPositional = function (dest, options) { - if (_.isArray(dest)) { - dest = _.first(dest); - } - // make sure required is not specified - if (options.required) { - throw new Error('"required" is an invalid argument for positionals.'); - } - - // mark positional arguments as required if at least one is - // always required - if (options.nargs !== $$.OPTIONAL && options.nargs !== $$.ZERO_OR_MORE) { - options.required = true; - } - if (options.nargs === $$.ZERO_OR_MORE && options.defaultValue === undefined) { - options.required = true; - } - - // return the keyword arguments with no option strings - options.dest = dest; - options.optionStrings = []; - return options; -}; - -ActionContainer.prototype._getOptional = function (args, options) { - var prefixChars = this.prefixChars; - var optionStrings = []; - var optionStringsLong = []; - - // determine short and long option strings - args.forEach(function (optionString) { - // error on strings that don't start with an appropriate prefix - if (prefixChars.indexOf(optionString[0]) < 0) { - throw new Error(format('Invalid option string "%s": must start with a "%s".', - optionString, - prefixChars - )); - } - - // strings starting with two prefix characters are long options - optionStrings.push(optionString); - if (optionString.length > 1 && prefixChars.indexOf(optionString[1]) >= 0) { - optionStringsLong.push(optionString); - } - }); - - // infer dest, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' - var dest = options.dest || null; - delete options.dest; - - if (!dest) { - var optionStringDest = optionStringsLong.length ? optionStringsLong[0] :optionStrings[0]; - dest = _.str.strip(optionStringDest, this.prefixChars); - - if (dest.length === 0) { - throw new Error( - format('dest= is required for options like "%s"', optionStrings.join(', ')) - ); - } - dest = dest.replace(/-/g, '_'); - } - - // return the updated keyword arguments - options.dest = dest; - options.optionStrings = optionStrings; - - return options; -}; - -ActionContainer.prototype._popActionClass = function (options, defaultValue) { - defaultValue = defaultValue || null; - - var action = (options.action || defaultValue); - delete options.action; - - var actionClass = this._registryGet('action', action, action); - return actionClass; -}; - -ActionContainer.prototype._getHandler = function () { - var handlerString = this.conflictHandler; - var handlerFuncName = "_handleConflict" + _.str.capitalize(handlerString); - var func = this[handlerFuncName]; - if (typeof func === 'undefined') { - var msg = "invalid conflict resolution value: " + handlerString; - throw new Error(msg); - } else { - return func; - } -}; - -ActionContainer.prototype._checkConflict = function (action) { - var optionStringActions = this._optionStringActions; - var conflictOptionals = []; - - // find all options that conflict with this option - // collect pairs, the string, and an existing action that it conflicts with - action.optionStrings.forEach(function (optionString) { - var conflOptional = optionStringActions[optionString]; - if (typeof conflOptional !== 'undefined') { - conflictOptionals.push([optionString, conflOptional]); - } - }); - - if (conflictOptionals.length > 0) { - var conflictHandler = this._getHandler(); - conflictHandler.call(this, action, conflictOptionals); - } -}; - -ActionContainer.prototype._handleConflictError = function (action, conflOptionals) { - var conflicts = _.map(conflOptionals, function (pair) {return pair[0]; }); - conflicts = conflicts.join(', '); - throw argumentErrorHelper( - action, - format('Conflicting option string(s): %s', conflicts) - ); -}; - -ActionContainer.prototype._handleConflictResolve = function (action, conflOptionals) { - // remove all conflicting options - var self = this; - conflOptionals.forEach(function (pair) { - var optionString = pair[0]; - var conflictingAction = pair[1]; - // remove the conflicting option string - var i = conflictingAction.optionStrings.indexOf(optionString); - if (i >= 0) { - conflictingAction.optionStrings.splice(i, 1); - } - delete self._optionStringActions[optionString]; - // if the option now has no option string, remove it from the - // container holding it - if (conflictingAction.optionStrings.length === 0) { - conflictingAction.container._removeAction(conflictingAction); - } - }); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argparse.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argparse.js deleted file mode 100644 index f2a2c51d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argparse.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -module.exports.ArgumentParser = require('./argument_parser.js'); -module.exports.Namespace = require('./namespace'); -module.exports.Action = require('./action'); -module.exports.HelpFormatter = require('./help/formatter.js'); -module.exports.Const = require('./const.js'); - -module.exports.ArgumentDefaultsHelpFormatter = - require('./help/added_formatters.js').ArgumentDefaultsHelpFormatter; -module.exports.RawDescriptionHelpFormatter = - require('./help/added_formatters.js').RawDescriptionHelpFormatter; -module.exports.RawTextHelpFormatter = - require('./help/added_formatters.js').RawTextHelpFormatter; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/error.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/error.js deleted file mode 100644 index c8a02a08..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/error.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; - - -var format = require('util').format; - - -var ERR_CODE = 'ARGError'; - -/*:nodoc:* - * argumentError(argument, message) -> TypeError - * - argument (Object): action with broken argument - * - message (String): error message - * - * Error format helper. An error from creating or using an argument - * (optional or positional). The string value of this exception - * is the message, augmented with information - * about the argument that caused it. - * - * #####Example - * - * var argumentErrorHelper = require('./argument/error'); - * if (conflictOptionals.length > 0) { - * throw argumentErrorHelper( - * action, - * format('Conflicting option string(s): %s', conflictOptionals.join(', ')) - * ); - * } - * - **/ -module.exports = function (argument, message) { - var argumentName = null; - var errMessage; - var err; - - if (argument.getName) { - argumentName = argument.getName(); - } else { - argumentName = '' + argument; - } - - if (!argumentName) { - errMessage = message; - } else { - errMessage = format('argument "%s": %s', argumentName, message); - } - - err = new TypeError(errMessage); - err.code = ERR_CODE; - return err; -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/exclusive.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/exclusive.js deleted file mode 100644 index 8287e00d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/exclusive.js +++ /dev/null @@ -1,54 +0,0 @@ -/** internal - * class MutuallyExclusiveGroup - * - * Group arguments. - * By default, ArgumentParser groups command-line arguments - * into “positional arguments†and “optional arguments†- * when displaying help messages. When there is a better - * conceptual grouping of arguments than this default one, - * appropriate groups can be created using the addArgumentGroup() method - * - * This class inherited from [[ArgumentContainer]] - **/ -'use strict'; - -var util = require('util'); - -var ArgumentGroup = require('./group'); - -/** - * new MutuallyExclusiveGroup(container, options) - * - container (object): main container - * - options (object): options.required -> true/false - * - * `required` could be an argument itself, but making it a property of - * the options argument is more consistent with the JS adaptation of the Python) - **/ -var MutuallyExclusiveGroup = module.exports = function MutuallyExclusiveGroup(container, options) { - var required; - options = options || {}; - required = options.required || false; - ArgumentGroup.call(this, container); - this.required = required; - -}; -util.inherits(MutuallyExclusiveGroup, ArgumentGroup); - - -MutuallyExclusiveGroup.prototype._addAction = function (action) { - var msg; - if (action.required) { - msg = 'mutually exclusive arguments must be optional'; - throw new Error(msg); - } - action = this._container._addAction(action); - this._groupActions.push(action); - return action; -}; - - -MutuallyExclusiveGroup.prototype._removeAction = function (action) { - this._container._removeAction(action); - this._groupActions.remove(action); -}; - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/group.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/group.js deleted file mode 100644 index 58b271f2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument/group.js +++ /dev/null @@ -1,75 +0,0 @@ -/** internal - * class ArgumentGroup - * - * Group arguments. - * By default, ArgumentParser groups command-line arguments - * into “positional arguments†and “optional arguments†- * when displaying help messages. When there is a better - * conceptual grouping of arguments than this default one, - * appropriate groups can be created using the addArgumentGroup() method - * - * This class inherited from [[ArgumentContainer]] - **/ -'use strict'; - -var util = require('util'); - -var ActionContainer = require('../action_container'); - - -/** - * new ArgumentGroup(container, options) - * - container (object): main container - * - options (object): hash of group options - * - * #### options - * - **prefixChars** group name prefix - * - **argumentDefault** default argument value - * - **title** group title - * - **description** group description - * - **/ -var ArgumentGroup = module.exports = function ArgumentGroup(container, options) { - - options = options || {}; - - // add any missing keyword arguments by checking the container - options.conflictHandler = (options.conflictHandler || container.conflictHandler); - options.prefixChars = (options.prefixChars || container.prefixChars); - options.argumentDefault = (options.argumentDefault || container.argumentDefault); - - ActionContainer.call(this, options); - - // group attributes - this.title = options.title; - this._groupActions = []; - - // share most attributes with the container - this._container = container; - this._registries = container._registries; - this._actions = container._actions; - this._optionStringActions = container._optionStringActions; - this._defaults = container._defaults; - this._hasNegativeNumberOptionals = container._hasNegativeNumberOptionals; - this._mutuallyExclusiveGroups = container._mutuallyExclusiveGroups; -}; -util.inherits(ArgumentGroup, ActionContainer); - - -ArgumentGroup.prototype._addAction = function (action) { - // Parent add action - action = ActionContainer.prototype._addAction.call(this, action); - this._groupActions.push(action); - return action; -}; - - -ArgumentGroup.prototype._removeAction = function (action) { - // Parent remove action - ActionContainer.prototype._removeAction.call(this, action); - var actionIndex = this._groupActions.indexOf(action); - if (actionIndex >= 0) { - this._groupActions.splice(actionIndex, 1); - } -}; - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument_parser.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument_parser.js deleted file mode 100644 index 97cf0982..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/argument_parser.js +++ /dev/null @@ -1,1165 +0,0 @@ -/** - * class ArgumentParser - * - * Object for parsing command line strings into js objects. - * - * Inherited from [[ActionContainer]] - **/ -'use strict'; - -var util = require('util'); -var format = require('util').format; -var Path = require('path'); - -var _ = require('underscore'); -_.str = require('underscore.string'); - -// Constants -var $$ = require('./const'); - -var ActionContainer = require('./action_container'); - -// Errors -var argumentErrorHelper = require('./argument/error'); - -var HelpFormatter = require('./help/formatter'); - -var Namespace = require('./namespace'); - - -/** - * new ArgumentParser(options) - * - * Create a new ArgumentParser object. - * - * ##### Options: - * - `prog` The name of the program (default: sys.argv[0]) - * - `usage` A usage message (default: auto-generated from arguments) - * - `description` A description of what the program does - * - `epilog` Text following the argument descriptions - * - `parents` Parsers whose arguments should be copied into this one - * - `formatterClass` HelpFormatter class for printing help messages - * - `prefixChars` Characters that prefix optional arguments - * - `fromfilePrefixChars` Characters that prefix files containing additional arguments - * - `argumentDefault` The default value for all arguments - * - `addHelp` Add a -h/-help option - * - `conflictHandler` Specifies how to handle conflicting argument names - * - `debug` Enable debug mode. Argument errors throw exception in - * debug mode and process.exit in normal. Used for development and - * testing (default: false) - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#argumentparser-objects - **/ -var ArgumentParser = module.exports = function ArgumentParser(options) { - var self = this; - options = options || {}; - - options.description = (options.description || null); - options.argumentDefault = (options.argumentDefault || null); - options.prefixChars = (options.prefixChars || '-'); - options.conflictHandler = (options.conflictHandler || 'error'); - ActionContainer.call(this, options); - - options.addHelp = (options.addHelp === undefined || !!options.addHelp); - options.parents = (options.parents || []); - // default program name - options.prog = (options.prog || Path.basename(process.argv[1])); - this.prog = options.prog; - this.usage = options.usage; - this.epilog = options.epilog; - this.version = options.version; - - this.debug = (options.debug === true); - - this.formatterClass = (options.formatterClass || HelpFormatter); - this.fromfilePrefixChars = options.fromfilePrefixChars || null; - this._positionals = this.addArgumentGroup({title: 'Positional arguments'}); - this._optionals = this.addArgumentGroup({title: 'Optional arguments'}); - this._subparsers = null; - - // register types - var FUNCTION_IDENTITY = function (o) { - return o; - }; - this.register('type', 'auto', FUNCTION_IDENTITY); - this.register('type', null, FUNCTION_IDENTITY); - this.register('type', 'int', function (x) { - var result = parseInt(x, 10); - if (isNaN(result)) { - throw new Error(x + ' is not a valid integer.'); - } - return result; - }); - this.register('type', 'float', function (x) { - var result = parseFloat(x); - if (isNaN(result)) { - throw new Error(x + ' is not a valid float.'); - } - return result; - }); - this.register('type', 'string', function (x) { - return '' + x; - }); - - // add help and version arguments if necessary - var defaultPrefix = (this.prefixChars.indexOf('-') > -1) ? '-' : this.prefixChars[0]; - if (options.addHelp) { - this.addArgument( - [defaultPrefix + 'h', defaultPrefix + defaultPrefix + 'help'], - { - action: 'help', - defaultValue: $$.SUPPRESS, - help: 'Show this help message and exit.' - } - ); - } - if (this.version !== undefined) { - this.addArgument( - [defaultPrefix + 'v', defaultPrefix + defaultPrefix + 'version'], - { - action: 'version', - version: this.version, - defaultValue: $$.SUPPRESS, - help: "Show program's version number and exit." - } - ); - } - - // add parent arguments and defaults - options.parents.forEach(function (parent) { - self._addContainerActions(parent); - if (parent._defaults !== undefined) { - for (var defaultKey in parent._defaults) { - if (parent._defaults.hasOwnProperty(defaultKey)) { - self._defaults[defaultKey] = parent._defaults[defaultKey]; - } - } - } - }); - -}; -util.inherits(ArgumentParser, ActionContainer); - -/** - * ArgumentParser#addSubparsers(options) -> [[ActionSubparsers]] - * - options (object): hash of options see [[ActionSubparsers.new]] - * - * See also [subcommands][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#sub-commands - **/ -ArgumentParser.prototype.addSubparsers = function (options) { - if (!!this._subparsers) { - this.error('Cannot have multiple subparser arguments.'); - } - - options = options || {}; - options.debug = (this.debug === true); - options.optionStrings = []; - options.parserClass = (options.parserClass || ArgumentParser); - - - if (!!options.title || !!options.description) { - - this._subparsers = this.addArgumentGroup({ - title: (options.title || 'subcommands'), - description: options.description - }); - delete options.title; - delete options.description; - - } else { - this._subparsers = this._positionals; - } - - // prog defaults to the usage message of this parser, skipping - // optional arguments and with no "usage:" prefix - if (!options.prog) { - var formatter = this._getFormatter(); - var positionals = this._getPositionalActions(); - var groups = this._mutuallyExclusiveGroups; - formatter.addUsage(this.usage, positionals, groups, ''); - options.prog = _.str.strip(formatter.formatHelp()); - } - - // create the parsers action and add it to the positionals list - var ParsersClass = this._popActionClass(options, 'parsers'); - var action = new ParsersClass(options); - this._subparsers._addAction(action); - - // return the created parsers action - return action; -}; - -ArgumentParser.prototype._addAction = function (action) { - if (action.isOptional()) { - this._optionals._addAction(action); - } else { - this._positionals._addAction(action); - } - return action; -}; - -ArgumentParser.prototype._getOptionalActions = function () { - return this._actions.filter(function (action) { - return action.isOptional(); - }); -}; - -ArgumentParser.prototype._getPositionalActions = function () { - return this._actions.filter(function (action) { - return action.isPositional(); - }); -}; - - -/** - * ArgumentParser#parseArgs(args, namespace) -> Namespace|Object - * - args (array): input elements - * - namespace (Namespace|Object): result object - * - * Parsed args and throws error if some arguments are not recognized - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#the-parse-args-method - **/ -ArgumentParser.prototype.parseArgs = function (args, namespace) { - var argv; - var result = this.parseKnownArgs(args, namespace); - - args = result[0]; - argv = result[1]; - if (argv && argv.length > 0) { - this.error( - format('Unrecognized arguments: %s.', argv.join(' ')) - ); - } - return args; -}; - -/** - * ArgumentParser#parseKnownArgs(args, namespace) -> array - * - args (array): input options - * - namespace (Namespace|Object): result object - * - * Parse known arguments and return tuple of result object - * and unknown args - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#partial-parsing - **/ -ArgumentParser.prototype.parseKnownArgs = function (args, namespace) { - var self = this; - - // args default to the system args - args = args || process.argv.slice(2); - - // default Namespace built from parser defaults - namespace = namespace || new Namespace(); - - self._actions.forEach(function (action) { - if (action.dest !== $$.SUPPRESS) { - if (!_.has(namespace, action.dest)) { - if (action.defaultValue !== $$.SUPPRESS) { - var defaultValue = action.defaultValue; - if (_.isString(action.defaultValue)) { - defaultValue = self._getValue(action, defaultValue); - } - namespace[action.dest] = defaultValue; - } - } - } - }); - - _.keys(self._defaults).forEach(function (dest) { - namespace[dest] = self._defaults[dest]; - }); - - // parse the arguments and exit if there are any errors - try { - var res = this._parseKnownArgs(args, namespace); - - namespace = res[0]; - args = res[1]; - if (_.has(namespace, $$._UNRECOGNIZED_ARGS_ATTR)) { - args = _.union(args, namespace[$$._UNRECOGNIZED_ARGS_ATTR]); - delete namespace[$$._UNRECOGNIZED_ARGS_ATTR]; - } - return [namespace, args]; - } catch (e) { - this.error(e); - } -}; - -ArgumentParser.prototype._parseKnownArgs = function (argStrings, namespace) { - var self = this; - - var extras = []; - - // replace arg strings that are file references - if (this.fromfilePrefixChars !== null) { - argStrings = this._readArgsFromFiles(argStrings); - } - // map all mutually exclusive arguments to the other arguments - // they can't occur with - // Python has 'conflicts = action_conflicts.setdefault(mutex_action, [])' - // though I can't conceive of a way in which an action could be a member - // of two different mutually exclusive groups. - - function actionHash(action) { - // some sort of hashable key for this action - // action itself cannot be a key in actionConflicts - // I think getName() (join of optionStrings) is unique enough - return action.getName(); - } - var conflicts, key; - var actionConflicts = {}; - this._mutuallyExclusiveGroups.forEach(function (mutexGroup) { - mutexGroup._groupActions.forEach(function (mutexAction, i, groupActions) { - key = actionHash(mutexAction); - if (!_.has(actionConflicts, key)) { - actionConflicts[key] = []; - } - conflicts = actionConflicts[key]; - conflicts.push.apply(conflicts, groupActions.slice(0, i)); - conflicts.push.apply(conflicts, groupActions.slice(i + 1)); - }); - }); - - // find all option indices, and determine the arg_string_pattern - // which has an 'O' if there is an option at an index, - // an 'A' if there is an argument, or a '-' if there is a '--' - var optionStringIndices = {}; - - var argStringPatternParts = []; - - argStrings.forEach(function (argString, argStringIndex) { - if (argString === '--') { - argStringPatternParts.push('-'); - while (argStringIndex < argStrings.length) { - argStringPatternParts.push('A'); - argStringIndex++; - } - } - // otherwise, add the arg to the arg strings - // and note the index if it was an option - else { - var pattern; - var optionTuple = self._parseOptional(argString); - if (!optionTuple) { - pattern = 'A'; - } - else { - optionStringIndices[argStringIndex] = optionTuple; - pattern = 'O'; - } - argStringPatternParts.push(pattern); - } - }); - var argStringsPattern = argStringPatternParts.join(''); - - var seenActions = []; - var seenNonDefaultActions = []; - - - function takeAction(action, argumentStrings, optionString) { - seenActions.push(action); - var argumentValues = self._getValues(action, argumentStrings); - - // error if this argument is not allowed with other previously - // seen arguments, assuming that actions that use the default - // value don't really count as "present" - if (argumentValues !== action.defaultValue) { - seenNonDefaultActions.push(action); - if (!!actionConflicts[actionHash(action)]) { - actionConflicts[actionHash(action)].forEach(function (actionConflict) { - if (seenNonDefaultActions.indexOf(actionConflict) >= 0) { - throw argumentErrorHelper( - action, - format('Not allowed with argument "%s".', actionConflict.getName()) - ); - } - }); - } - } - - if (argumentValues !== $$.SUPPRESS) { - action.call(self, namespace, argumentValues, optionString); - } - } - - function consumeOptional(startIndex) { - // get the optional identified at this index - var optionTuple = optionStringIndices[startIndex]; - var action = optionTuple[0]; - var optionString = optionTuple[1]; - var explicitArg = optionTuple[2]; - - // identify additional optionals in the same arg string - // (e.g. -xyz is the same as -x -y -z if no args are required) - var actionTuples = []; - - var args, argCount, start, stop; - - while (true) { - if (!action) { - extras.push(argStrings[startIndex]); - return startIndex + 1; - } - if (!!explicitArg) { - argCount = self._matchArgument(action, 'A'); - - // if the action is a single-dash option and takes no - // arguments, try to parse more single-dash options out - // of the tail of the option string - var chars = self.prefixChars; - if (argCount === 0 && chars.indexOf(optionString[1]) < 0) { - actionTuples.push([action, [], optionString]); - optionString = optionString[0] + explicitArg[0]; - var newExplicitArg = explicitArg.slice(1) || null; - var optionalsMap = self._optionStringActions; - - if (_.keys(optionalsMap).indexOf(optionString) >= 0) { - action = optionalsMap[optionString]; - explicitArg = newExplicitArg; - } - else { - var msg = 'ignored explicit argument %r'; - throw argumentErrorHelper(action, msg); - } - } - // if the action expect exactly one argument, we've - // successfully matched the option; exit the loop - else if (argCount === 1) { - stop = startIndex + 1; - args = [explicitArg]; - actionTuples.push([action, args, optionString]); - break; - } - // error if a double-dash option did not use the - // explicit argument - else { - var message = 'ignored explicit argument %r'; - throw argumentErrorHelper(action, _.str.sprintf(message, explicitArg)); - } - } - // if there is no explicit argument, try to match the - // optional's string arguments with the following strings - // if successful, exit the loop - else { - - start = startIndex + 1; - var selectedPatterns = argStringsPattern.substr(start); - - argCount = self._matchArgument(action, selectedPatterns); - stop = start + argCount; - - - args = argStrings.slice(start, stop); - - actionTuples.push([action, args, optionString]); - break; - } - - } - - // add the Optional to the list and return the index at which - // the Optional's string args stopped - if (actionTuples.length < 1) { - throw new Error('length should be > 0'); - } - for (var i = 0; i < actionTuples.length; i++) { - takeAction.apply(self, actionTuples[i]); - } - return stop; - } - - // the list of Positionals left to be parsed; this is modified - // by consume_positionals() - var positionals = self._getPositionalActions(); - - function consumePositionals(startIndex) { - // match as many Positionals as possible - var selectedPattern = argStringsPattern.substr(startIndex); - var argCounts = self._matchArgumentsPartial(positionals, selectedPattern); - - // slice off the appropriate arg strings for each Positional - // and add the Positional and its args to the list - _.zip(positionals, argCounts).forEach(function (item) { - var action = item[0]; - var argCount = item[1]; - if (argCount === undefined) { - return; - } - var args = argStrings.slice(startIndex, startIndex + argCount); - - startIndex += argCount; - takeAction(action, args); - }); - - // slice off the Positionals that we just parsed and return the - // index at which the Positionals' string args stopped - positionals = positionals.slice(argCounts.length); - return startIndex; - } - - // consume Positionals and Optionals alternately, until we have - // passed the last option string - var startIndex = 0; - var position; - - var maxOptionStringIndex = -1; - if (!!optionStringIndices) { - for (position in optionStringIndices) { - maxOptionStringIndex = Math.max(maxOptionStringIndex, parseInt(position, 10)); - } - } - - var positionalsEndIndex, nextOptionStringIndex; - - while (startIndex <= maxOptionStringIndex) { - // consume any Positionals preceding the next option - nextOptionStringIndex = null; - for (position in optionStringIndices) { - position = parseInt(position, 10); - if (position >= startIndex) { - if (nextOptionStringIndex !== null) { - nextOptionStringIndex = Math.min(nextOptionStringIndex, position); - } - else { - nextOptionStringIndex = position; - } - } - } - - if (startIndex !== nextOptionStringIndex) { - positionalsEndIndex = consumePositionals(startIndex); - // only try to parse the next optional if we didn't consume - // the option string during the positionals parsing - if (positionalsEndIndex > startIndex) { - startIndex = positionalsEndIndex; - continue; - } - else { - startIndex = positionalsEndIndex; - } - } - - // if we consumed all the positionals we could and we're not - // at the index of an option string, there were extra arguments - if (!optionStringIndices[startIndex]) { - var strings = argStrings.slice(startIndex, nextOptionStringIndex); - extras = extras.concat(strings); - startIndex = nextOptionStringIndex; - } - // consume the next optional and any arguments for it - startIndex = consumeOptional(startIndex); - } - - // consume any positionals following the last Optional - var stopIndex = consumePositionals(startIndex); - - // if we didn't consume all the argument strings, there were extras - extras = extras.concat(_.rest(argStrings, stopIndex)); - - // if we didn't use all the Positional objects, there were too few - // arg strings supplied. - if (positionals.length > 0) { - self.error('too few arguments'); - } - - // make sure all required actions were present - self._actions.forEach(function (action) { - if (action.required) { - if (_.indexOf(seenActions, action) < 0) { - self.error(format('Argument "%s" is required', action.getName())); - } - } - }); - - // make sure all required groups have one option present - var actionUsed = false; - self._mutuallyExclusiveGroups.forEach(function (group) { - if (group.required) { - actionUsed = _.any(group._groupActions, function (action) { - return _.contains(seenNonDefaultActions, action); - }); - - // if no actions were used, report the error - if (!actionUsed) { - var names = []; - group._groupActions.forEach(function (action) { - if (action.help !== $$.SUPPRESS) { - names.push(action.getName()); - } - }); - names = names.join(' '); - var msg = 'one of the arguments ' + names + ' is required'; - self.error(msg); - } - } - }); - - // return the updated namespace and the extra arguments - return [namespace, extras]; -}; - -ArgumentParser.prototype._readArgsFromFiles = function (argStrings) { - // expand arguments referencing files - var _this = this; - var fs = require('fs'); - var newArgStrings = []; - argStrings.forEach(function (argString) { - if (_this.fromfilePrefixChars.indexOf(argString[0]) < 0) { - // for regular arguments, just add them back into the list - newArgStrings.push(argString); - } else { - // replace arguments referencing files with the file content - try { - var argstrs = []; - var filename = argString.slice(1); - var content = fs.readFileSync(filename, 'utf8'); - content = content.trim().split('\n'); - content.forEach(function (argLine) { - _this.convertArgLineToArgs(argLine).forEach(function (arg) { - argstrs.push(arg); - }); - argstrs = _this._readArgsFromFiles(argstrs); - }); - newArgStrings.push.apply(newArgStrings, argstrs); - } catch (error) { - return _this.error(error.message); - } - } - }); - return newArgStrings; -}; - -ArgumentParser.prototype.convertArgLineToArgs = function (argLine) { - return [argLine]; -}; - -ArgumentParser.prototype._matchArgument = function (action, regexpArgStrings) { - - // match the pattern for this action to the arg strings - var regexpNargs = new RegExp('^' + this._getNargsPattern(action)); - var matches = regexpArgStrings.match(regexpNargs); - var message; - - // throw an exception if we weren't able to find a match - if (!matches) { - switch (action.nargs) { - case undefined: - case null: - message = 'Expected one argument.'; - break; - case $$.OPTIONAL: - message = 'Expected at most one argument.'; - break; - case $$.ONE_OR_MORE: - message = 'Expected at least one argument.'; - break; - default: - message = 'Expected %s argument(s)'; - } - - throw argumentErrorHelper( - action, - format(message, action.nargs) - ); - } - // return the number of arguments matched - return matches[1].length; -}; - -ArgumentParser.prototype._matchArgumentsPartial = function (actions, regexpArgStrings) { - // progressively shorten the actions list by slicing off the - // final actions until we find a match - var self = this; - var result = []; - var actionSlice, pattern, matches; - var i, j; - - var getLength = function (string) { - return string.length; - }; - - for (i = actions.length; i > 0; i -= 1) { - pattern = ''; - actionSlice = actions.slice(0, i); - for (j in actionSlice) { - pattern += self._getNargsPattern(actionSlice[j]); - } - - pattern = new RegExp('^' + pattern); - matches = regexpArgStrings.match(pattern); - - if (matches && matches.length > 0) { - // need only groups - matches = matches.splice(1); - result = result.concat(matches.map(getLength)); - break; - } - } - - // return the list of arg string counts - return result; -}; - -ArgumentParser.prototype._parseOptional = function (argString) { - var action, optionString, argExplicit, optionTuples; - - // if it's an empty string, it was meant to be a positional - if (!argString) { - return null; - } - - // if it doesn't start with a prefix, it was meant to be positional - if (this.prefixChars.indexOf(argString[0]) < 0) { - return null; - } - - // if the option string is present in the parser, return the action - if (!!this._optionStringActions[argString]) { - return [this._optionStringActions[argString], argString, null]; - } - - // if it's just a single character, it was meant to be positional - if (argString.length === 1) { - return null; - } - - // if the option string before the "=" is present, return the action - if (argString.indexOf('=') >= 0) { - var argStringSplit = argString.split('='); - optionString = argStringSplit[0]; - argExplicit = argStringSplit[1]; - - if (!!this._optionStringActions[optionString]) { - action = this._optionStringActions[optionString]; - return [action, optionString, argExplicit]; - } - } - - // search through all possible prefixes of the option string - // and all actions in the parser for possible interpretations - optionTuples = this._getOptionTuples(argString); - - // if multiple actions match, the option string was ambiguous - if (optionTuples.length > 1) { - var optionStrings = optionTuples.map(function (optionTuple) { - return optionTuple[1]; - }); - this.error(format( - 'Ambiguous option: "%s" could match %s.', - argString, optionStrings.join(', ') - )); - // if exactly one action matched, this segmentation is good, - // so return the parsed action - } else if (optionTuples.length === 1) { - return optionTuples[0]; - } - - // if it was not found as an option, but it looks like a negative - // number, it was meant to be positional - // unless there are negative-number-like options - if (argString.match(this._regexpNegativeNumber)) { - if (!_.any(this._hasNegativeNumberOptionals)) { - return null; - } - } - // if it contains a space, it was meant to be a positional - if (argString.search(' ') >= 0) { - return null; - } - - // it was meant to be an optional but there is no such option - // in this parser (though it might be a valid option in a subparser) - return [null, argString, null]; -}; - -ArgumentParser.prototype._getOptionTuples = function (optionString) { - var result = []; - var chars = this.prefixChars; - var optionPrefix; - var argExplicit; - var action; - var actionOptionString; - - // option strings starting with two prefix characters are only split at - // the '=' - if (chars.indexOf(optionString[0]) >= 0 && chars.indexOf(optionString[1]) >= 0) { - if (optionString.indexOf('=') >= 0) { - var optionStringSplit = optionString.split('=', 1); - - optionPrefix = optionStringSplit[0]; - argExplicit = optionStringSplit[1]; - } else { - optionPrefix = optionString; - argExplicit = null; - } - - for (actionOptionString in this._optionStringActions) { - if (actionOptionString.substr(0, optionPrefix.length) === optionPrefix) { - action = this._optionStringActions[actionOptionString]; - result.push([action, actionOptionString, argExplicit]); - } - } - - // single character options can be concatenated with their arguments - // but multiple character options always have to have their argument - // separate - } else if (chars.indexOf(optionString[0]) >= 0 && chars.indexOf(optionString[1]) < 0) { - optionPrefix = optionString; - argExplicit = null; - var optionPrefixShort = optionString.substr(0, 2); - var argExplicitShort = optionString.substr(2); - - for (actionOptionString in this._optionStringActions) { - action = this._optionStringActions[actionOptionString]; - if (actionOptionString === optionPrefixShort) { - result.push([action, actionOptionString, argExplicitShort]); - } else if (actionOptionString.substr(0, optionPrefix.length) === optionPrefix) { - result.push([action, actionOptionString, argExplicit]); - } - } - - // shouldn't ever get here - } else { - throw new Error(format('Unexpected option string: %s.', optionString)); - } - // return the collected option tuples - return result; -}; - -ArgumentParser.prototype._getNargsPattern = function (action) { - // in all examples below, we have to allow for '--' args - // which are represented as '-' in the pattern - var regexpNargs; - - switch (action.nargs) { - // the default (null) is assumed to be a single argument - case undefined: - case null: - regexpNargs = '(-*A-*)'; - break; - // allow zero or more arguments - case $$.OPTIONAL: - regexpNargs = '(-*A?-*)'; - break; - // allow zero or more arguments - case $$.ZERO_OR_MORE: - regexpNargs = '(-*[A-]*)'; - break; - // allow one or more arguments - case $$.ONE_OR_MORE: - regexpNargs = '(-*A[A-]*)'; - break; - // allow any number of options or arguments - case $$.REMAINDER: - regexpNargs = '([-AO]*)'; - break; - // allow one argument followed by any number of options or arguments - case $$.PARSER: - regexpNargs = '(-*A[-AO]*)'; - break; - // all others should be integers - default: - regexpNargs = '(-*' + _.str.repeat('-*A', action.nargs) + '-*)'; - } - - // if this is an optional action, -- is not allowed - if (action.isOptional()) { - regexpNargs = regexpNargs.replace(/-\*/g, ''); - regexpNargs = regexpNargs.replace(/-/g, ''); - } - - // return the pattern - return regexpNargs; -}; - -// -// Value conversion methods -// - -ArgumentParser.prototype._getValues = function (action, argStrings) { - var self = this; - - // for everything but PARSER args, strip out '--' - if (action.nargs !== $$.PARSER && action.nargs !== $$.REMAINDER) { - argStrings = argStrings.filter(function (arrayElement) { - return arrayElement !== '--'; - }); - } - - var value, argString; - - // optional argument produces a default when not present - if (argStrings.length === 0 && action.nargs === $$.OPTIONAL) { - - value = (action.isOptional()) ? action.constant: action.defaultValue; - - if (typeof(value) === 'string') { - value = this._getValue(action, value); - this._checkValue(action, value); - } - - // when nargs='*' on a positional, if there were no command-line - // args, use the default if it is anything other than None - } else if (argStrings.length === 0 && action.nargs === $$.ZERO_OR_MORE && - action.optionStrings.length === 0) { - - value = (action.defaultValue || argStrings); - this._checkValue(action, value); - - // single argument or optional argument produces a single value - } else if (argStrings.length === 1 && - (!action.nargs || action.nargs === $$.OPTIONAL)) { - - argString = argStrings[0]; - value = this._getValue(action, argString); - this._checkValue(action, value); - - // REMAINDER arguments convert all values, checking none - } else if (action.nargs === $$.REMAINDER) { - value = argStrings.map(function (v) { - return self._getValue(action, v); - }); - - // PARSER arguments convert all values, but check only the first - } else if (action.nargs === $$.PARSER) { - value = argStrings.map(function (v) { - return self._getValue(action, v); - }); - this._checkValue(action, value[0]); - - // all other types of nargs produce a list - } else { - value = argStrings.map(function (v) { - return self._getValue(action, v); - }); - value.forEach(function (v) { - self._checkValue(action, v); - }); - } - - // return the converted value - return value; -}; - -ArgumentParser.prototype._getValue = function (action, argString) { - var result; - - var typeFunction = this._registryGet('type', action.type, action.type); - if (!_.isFunction(typeFunction)) { - var message = format('%s is not callable', typeFunction); - throw argumentErrorHelper(action, message); - } - - // convert the value to the appropriate type - try { - result = typeFunction(argString); - - // ArgumentTypeErrors indicate errors - // If action.type is not a registered string, it is a function - // Try to deduce its name for inclusion in the error message - // Failing that, include the error message it raised. - } catch (e) { - var name = null; - if (_.isString(action.type)) { - name = action.type; - } else { - name = action.type.name || action.type.displayName || ''; - } - var msg = format('Invalid %s value: %s', name, argString); - if (name === '') {msg += '\n' + e.message; } - throw argumentErrorHelper(action, msg); - } - // return the converted value - return result; -}; - -ArgumentParser.prototype._checkValue = function (action, value) { - // converted value must be one of the choices (if specified) - var choices = action.choices; - if (!!choices) { - // choise for argument can by array or string - if ((_.isString(choices) || _.isArray(choices)) && - choices.indexOf(value) !== -1) { - return; - } - // choise for subparsers can by only hash - if (_.isObject(choices) && !_.isArray(choices) && choices[value]) { - return; - } - - if (_.isString(choices)) { - choices = choices.split('').join(', '); - } - else if (_.isArray(choices)) { - choices = choices.join(', '); - } - else { - choices = _.keys(choices).join(', '); - } - var message = format('Invalid choice: %s (choose from [%s])', value, choices); - throw argumentErrorHelper(action, message); - } -}; - -// -// Help formatting methods -// - -/** - * ArgumentParser#formatUsage -> string - * - * Return usage string - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#printing-help - **/ -ArgumentParser.prototype.formatUsage = function () { - var formatter = this._getFormatter(); - formatter.addUsage(this.usage, this._actions, this._mutuallyExclusiveGroups); - return formatter.formatHelp(); -}; - -/** - * ArgumentParser#formatHelp -> string - * - * Return help - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#printing-help - **/ -ArgumentParser.prototype.formatHelp = function () { - var formatter = this._getFormatter(); - - // usage - formatter.addUsage(this.usage, this._actions, this._mutuallyExclusiveGroups); - - // description - formatter.addText(this.description); - - // positionals, optionals and user-defined groups - this._actionGroups.forEach(function (actionGroup) { - formatter.startSection(actionGroup.title); - formatter.addText(actionGroup.description); - formatter.addArguments(actionGroup._groupActions); - formatter.endSection(); - }); - - // epilog - formatter.addText(this.epilog); - - // determine help from format above - return formatter.formatHelp(); -}; - -ArgumentParser.prototype._getFormatter = function () { - var FormatterClass = this.formatterClass; - var formatter = new FormatterClass({prog: this.prog}); - return formatter; -}; - -// -// Print functions -// - -/** - * ArgumentParser#printUsage() -> Void - * - * Print usage - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#printing-help - **/ -ArgumentParser.prototype.printUsage = function () { - this._printMessage(this.formatUsage()); -}; - -/** - * ArgumentParser#printHelp() -> Void - * - * Print help - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#printing-help - **/ -ArgumentParser.prototype.printHelp = function () { - this._printMessage(this.formatHelp()); -}; - -ArgumentParser.prototype._printMessage = function (message, stream) { - if (!stream) { - stream = process.stdout; - } - if (message) { - stream.write('' + message); - } -}; - -// -// Exit functions -// - -/** - * ArgumentParser#exit(status=0, message) -> Void - * - status (int): exit status - * - message (string): message - * - * Print message in stderr/stdout and exit program - **/ -ArgumentParser.prototype.exit = function (status, message) { - if (!!message) { - if (status === 0) { - this._printMessage(message); - } - else { - this._printMessage(message, process.stderr); - } - } - - process.exit(status); -}; - -/** - * ArgumentParser#error(message) -> Void - * - err (Error|string): message - * - * Error method Prints a usage message incorporating the message to stderr and - * exits. If you override this in a subclass, - * it should not return -- it should - * either exit or throw an exception. - * - **/ -ArgumentParser.prototype.error = function (err) { - var message; - if (err instanceof Error) { - if (this.debug === true) { - throw err; - } - message = err.message; - } - else { - message = err; - } - var msg = format('%s: error: %s', this.prog, message) + $$.EOL; - - if (this.debug === true) { - throw new Error(msg); - } - - this.printUsage(process.stderr); - - return this.exit(2, msg); -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/const.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/const.js deleted file mode 100644 index de831ba4..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/const.js +++ /dev/null @@ -1,18 +0,0 @@ -// -// Constants -// -module.exports.EOL = '\n'; - -module.exports.SUPPRESS = '==SUPPRESS=='; - -module.exports.OPTIONAL = '?'; - -module.exports.ZERO_OR_MORE = '*'; - -module.exports.ONE_OR_MORE = '+'; - -module.exports.PARSER = 'A...'; - -module.exports.REMAINDER = '...'; - -module.exports._UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/added_formatters.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/added_formatters.js deleted file mode 100644 index cd2f369b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/added_formatters.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; - -var util = require('util'); -var _ = require('underscore'); -_.str = require('underscore.string'); - -// Constants -var $$ = require('../const'); - -var HelpFormatter = require('./formatter.js'); - -/** - * new RawDescriptionHelpFormatter(options) - * new ArgumentParser({formatterClass: argparse.RawDescriptionHelpFormatter, ...}) - * - * Help message formatter which adds default values to argument help. - * - * Only the name of this class is considered a public API. All the methods - * provided by the class are considered an implementation detail. - **/ - -var ArgumentDefaultsHelpFormatter = function ArgumentDefaultsHelpFormatter(options) { - HelpFormatter.call(this, options); -}; - -util.inherits(ArgumentDefaultsHelpFormatter, HelpFormatter); - -ArgumentDefaultsHelpFormatter.prototype._getHelpString = function (action) { - var help = action.help; - if (action.help.indexOf('%(defaultValue)s') === -1) { - if (action.defaultValue !== $$.SUPPRESS) { - var defaulting_nargs = [$$.OPTIONAL, $$.ZERO_OR_MORE]; - if (action.isOptional() || (defaulting_nargs.indexOf(action.nargs) >= 0)) { - help += ' (default: %(defaultValue)s)'; - } - } - } - return help; -}; - -module.exports.ArgumentDefaultsHelpFormatter = ArgumentDefaultsHelpFormatter; - -/** - * new RawDescriptionHelpFormatter(options) - * new ArgumentParser({formatterClass: argparse.RawDescriptionHelpFormatter, ...}) - * - * Help message formatter which retains any formatting in descriptions. - * - * Only the name of this class is considered a public API. All the methods - * provided by the class are considered an implementation detail. - **/ - -var RawDescriptionHelpFormatter = function RawDescriptionHelpFormatter(options) { - HelpFormatter.call(this, options); -}; - -util.inherits(RawDescriptionHelpFormatter, HelpFormatter); - -RawDescriptionHelpFormatter.prototype._fillText = function (text, width, indent) { - var lines = text.split('\n'); - lines = lines.map(function (line) { - return _.str.rtrim(indent + line); - }); - return lines.join('\n'); -}; -module.exports.RawDescriptionHelpFormatter = RawDescriptionHelpFormatter; - -/** - * new RawTextHelpFormatter(options) - * new ArgumentParser({formatterClass: argparse.RawTextHelpFormatter, ...}) - * - * Help message formatter which retains formatting of all help text. - * - * Only the name of this class is considered a public API. All the methods - * provided by the class are considered an implementation detail. - **/ - -var RawTextHelpFormatter = function RawTextHelpFormatter(options) { - RawDescriptionHelpFormatter.call(this, options); -}; - -util.inherits(RawTextHelpFormatter, RawDescriptionHelpFormatter); - -RawTextHelpFormatter.prototype._splitLines = function (text) { - return text.split('\n'); -}; - -module.exports.RawTextHelpFormatter = RawTextHelpFormatter; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/formatter.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/formatter.js deleted file mode 100644 index 541d918b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/help/formatter.js +++ /dev/null @@ -1,803 +0,0 @@ -/** - * class HelpFormatter - * - * Formatter for generating usage messages and argument help strings. Only the - * name of this class is considered a public API. All the methods provided by - * the class are considered an implementation detail. - * - * Do not call in your code, use this class only for inherits your own forvatter - * - * ToDo add [additonal formatters][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#formatter-class - **/ -'use strict'; - -var _ = require('underscore'); -_.str = require('underscore.string'); - -// Constants -var $$ = require('../const'); - - -/*:nodoc:* internal - * new Support(parent, heding) - * - parent (object): parent section - * - heading (string): header string - * - **/ -function Section(parent, heading) { - this._parent = parent; - this._heading = heading; - this._items = []; -} - -/*:nodoc:* internal - * Section#addItem(callback) -> Void - * - callback (array): tuple with function and args - * - * Add function for single element - **/ -Section.prototype.addItem = function (callback) { - this._items.push(callback); -}; - -/*:nodoc:* internal - * Section#formatHelp(formatter) -> string - * - formatter (HelpFormatter): current formatter - * - * Form help section string - * - **/ -Section.prototype.formatHelp = function (formatter) { - var itemHelp, heading; - - // format the indented section - if (!!this._parent) { - formatter._indent(); - } - - itemHelp = this._items.map(function (item) { - var obj, func, args; - - obj = formatter; - func = item[0]; - args = item[1]; - return func.apply(obj, args); - }); - itemHelp = formatter._joinParts(itemHelp); - - if (!!this._parent) { - formatter._dedent(); - } - - // return nothing if the section was empty - if (!itemHelp) { - return ''; - } - - // add the heading if the section was non-empty - heading = ''; - if (!!this._heading && this._heading !== $$.SUPPRESS) { - var currentIndent = formatter.currentIndent; - heading = _.str.repeat(' ', currentIndent) + this._heading + ':' + $$.EOL; - } - - // join the section-initialize newline, the heading and the help - return formatter._joinParts([$$.EOL, heading, itemHelp, $$.EOL]); -}; - -/** - * new HelpFormatter(options) - * - * #### Options: - * - `prog`: program name - * - `indentIncriment`: indent step, default value 2 - * - `maxHelpPosition`: max help position, default value = 24 - * - `width`: line width - * - **/ -var HelpFormatter = module.exports = function HelpFormatter(options) { - options = options || {}; - - this._prog = options.prog; - - this._maxHelpPosition = options.maxHelpPosition || 24; - this._width = (options.width || ((process.env.COLUMNS || 80) - 2)); - - this._currentIndent = 0; - this._indentIncriment = options.indentIncriment || 2; - this._level = 0; - this._actionMaxLength = 0; - - this._rootSection = new Section(null); - this._currentSection = this._rootSection; - - this._whitespaceMatcher = new RegExp('\\s+', 'g'); - this._longBreakMatcher = new RegExp($$.EOL + $$.EOL + $$.EOL + '+', 'g'); -}; - -HelpFormatter.prototype._indent = function () { - this._currentIndent += this._indentIncriment; - this._level += 1; -}; - -HelpFormatter.prototype._dedent = function () { - this._currentIndent -= this._indentIncriment; - this._level -= 1; - if (this._currentIndent < 0) { - throw new Error('Indent decreased below 0.'); - } -}; - -HelpFormatter.prototype._addItem = function (func, args) { - this._currentSection.addItem([func, args]); -}; - -// -// Message building methods -// - -/** - * HelpFormatter#startSection(heading) -> Void - * - heading (string): header string - * - * Start new help section - * - * See alse [code example][1] - * - * ##### Example - * - * formatter.startSection(actionGroup.title); - * formatter.addText(actionGroup.description); - * formatter.addArguments(actionGroup._groupActions); - * formatter.endSection(); - * - **/ -HelpFormatter.prototype.startSection = function (heading) { - this._indent(); - var section = new Section(this._currentSection, heading); - var func = section.formatHelp.bind(section); - this._addItem(func, [this]); - this._currentSection = section; -}; - -/** - * HelpFormatter#endSection -> Void - * - * End help section - * - * ##### Example - * - * formatter.startSection(actionGroup.title); - * formatter.addText(actionGroup.description); - * formatter.addArguments(actionGroup._groupActions); - * formatter.endSection(); - **/ -HelpFormatter.prototype.endSection = function () { - this._currentSection = this._currentSection._parent; - this._dedent(); -}; - -/** - * HelpFormatter#addText(text) -> Void - * - text (string): plain text - * - * Add plain text into current section - * - * ##### Example - * - * formatter.startSection(actionGroup.title); - * formatter.addText(actionGroup.description); - * formatter.addArguments(actionGroup._groupActions); - * formatter.endSection(); - * - **/ -HelpFormatter.prototype.addText = function (text) { - if (!!text && text !== $$.SUPPRESS) { - this._addItem(this._formatText, [text]); - } -}; - -/** - * HelpFormatter#addUsage(usage, actions, groups, prefix) -> Void - * - usage (string): usage text - * - actions (array): actions list - * - groups (array): groups list - * - prefix (string): usage prefix - * - * Add usage data into current section - * - * ##### Example - * - * formatter.addUsage(this.usage, this._actions, []); - * return formatter.formatHelp(); - * - **/ -HelpFormatter.prototype.addUsage = function (usage, actions, groups, prefix) { - if (usage !== $$.SUPPRESS) { - this._addItem(this._formatUsage, [usage, actions, groups, prefix]); - } -}; - -/** - * HelpFormatter#addArgument(action) -> Void - * - action (object): action - * - * Add argument into current section - * - * Single variant of [[HelpFormatter#addArguments]] - **/ -HelpFormatter.prototype.addArgument = function (action) { - if (action.help !== $$.SUPPRESS) { - var self = this; - - // find all invocations - var invocations = [this._formatActionInvocation(action)]; - var invocationLength = invocations[0].length; - - var actionLength; - - if (!!action._getSubactions) { - this._indent(); - action._getSubactions().forEach(function (subaction) { - - var invocationNew = self._formatActionInvocation(subaction); - invocations.push(invocationNew); - invocationLength = Math.max(invocationLength, invocationNew.length); - - }); - this._dedent(); - } - - // update the maximum item length - actionLength = invocationLength + this._currentIndent; - this._actionMaxLength = Math.max(this._actionMaxLength, actionLength); - - // add the item to the list - this._addItem(this._formatAction, [action]); - } -}; - -/** - * HelpFormatter#addArguments(actions) -> Void - * - actions (array): actions list - * - * Mass add arguments into current section - * - * ##### Example - * - * formatter.startSection(actionGroup.title); - * formatter.addText(actionGroup.description); - * formatter.addArguments(actionGroup._groupActions); - * formatter.endSection(); - * - **/ -HelpFormatter.prototype.addArguments = function (actions) { - var self = this; - actions.forEach(function (action) { - self.addArgument(action); - }); -}; - -// -// Help-formatting methods -// - -/** - * HelpFormatter#formatHelp -> string - * - * Format help - * - * ##### Example - * - * formatter.addText(this.epilog); - * return formatter.formatHelp(); - * - **/ -HelpFormatter.prototype.formatHelp = function () { - var help = this._rootSection.formatHelp(this); - if (help) { - help = help.replace(this._longBreakMatcher, $$.EOL + $$.EOL); - help = _.str.strip(help, $$.EOL) + $$.EOL; - } - return help; -}; - -HelpFormatter.prototype._joinParts = function (partStrings) { - return partStrings.filter(function (part) { - return (!!part && part !== $$.SUPPRESS); - }).join(''); -}; - -HelpFormatter.prototype._formatUsage = function (usage, actions, groups, prefix) { - if (!prefix && !_.isString(prefix)) { - prefix = 'usage: '; - } - - actions = actions || []; - groups = groups || []; - - - // if usage is specified, use that - if (usage) { - usage = _.str.sprintf(usage, {prog: this._prog}); - - // if no optionals or positionals are available, usage is just prog - } else if (!usage && actions.length === 0) { - usage = this._prog; - - // if optionals and positionals are available, calculate usage - } else if (!usage) { - var prog = this._prog; - var optionals = []; - var positionals = []; - var actionUsage; - var textWidth; - - // split optionals from positionals - actions.forEach(function (action) { - if (action.isOptional()) { - optionals.push(action); - } else { - positionals.push(action); - } - }); - - // build full usage string - actionUsage = this._formatActionsUsage([].concat(optionals, positionals), groups); - usage = [prog, actionUsage].join(' '); - - // wrap the usage parts if it's too long - textWidth = this._width - this._currentIndent; - if ((prefix.length + usage.length) > textWidth) { - - // break usage into wrappable parts - var regexpPart = new RegExp('\\(.*?\\)+|\\[.*?\\]+|\\S+', 'g'); - var optionalUsage = this._formatActionsUsage(optionals, groups); - var positionalUsage = this._formatActionsUsage(positionals, groups); - - - var optionalParts = optionalUsage.match(regexpPart); - var positionalParts = positionalUsage.match(regexpPart) || []; - - if (optionalParts.join(' ') !== optionalUsage) { - throw new Error('assert "optionalParts.join(\' \') === optionalUsage"'); - } - if (positionalParts.join(' ') !== positionalUsage) { - throw new Error('assert "positionalParts.join(\' \') === positionalUsage"'); - } - - // helper for wrapping lines - var _getLines = function (parts, indent, prefix) { - var lines = []; - var line = []; - - var lineLength = !!prefix ? prefix.length - 1: indent.length - 1; - - parts.forEach(function (part) { - if (lineLength + 1 + part.length > textWidth) { - lines.push(indent + line.join(' ')); - line = []; - lineLength = indent.length - 1; - } - line.push(part); - lineLength += part.length + 1; - }); - - if (line) { - lines.push(indent + line.join(' ')); - } - if (prefix) { - lines[0] = lines[0].substr(indent.length); - } - return lines; - }; - - var lines, indent, parts; - // if prog is short, follow it with optionals or positionals - if (prefix.length + prog.length <= 0.75 * textWidth) { - indent = _.str.repeat(' ', (prefix.length + prog.length + 1)); - if (optionalParts) { - lines = [].concat( - _getLines([prog].concat(optionalParts), indent, prefix), - _getLines(positionalParts, indent) - ); - } else if (positionalParts) { - lines = _getLines([prog].concat(positionalParts), indent, prefix); - } else { - lines = [prog]; - } - - // if prog is long, put it on its own line - } else { - indent = _.str.repeat(' ', prefix.length); - parts = optionalParts + positionalParts; - lines = _getLines(parts, indent); - if (lines.length > 1) { - lines = [].concat( - _getLines(optionalParts, indent), - _getLines(positionalParts, indent) - ); - } - lines = [prog] + lines; - } - // join lines into usage - usage = lines.join($$.EOL); - } - } - - // prefix with 'usage:' - return prefix + usage + $$.EOL + $$.EOL; -}; - -HelpFormatter.prototype._formatActionsUsage = function (actions, groups) { - // find group indices and identify actions in groups - var groupActions = []; - var inserts = []; - var self = this; - - groups.forEach(function (group) { - var end; - var i; - - var start = actions.indexOf(group._groupActions[0]); - if (start >= 0) { - end = start + group._groupActions.length; - - //if (actions.slice(start, end) === group._groupActions) { - if (_.isEqual(actions.slice(start, end), group._groupActions)) { - group._groupActions.forEach(function (action) { - groupActions.push(action); - }); - - if (!group.required) { - if (!!inserts[start]) { - inserts[start] += ' ['; - } - else { - inserts[start] = '['; - } - inserts[end] = ']'; - } else { - if (!!inserts[start]) { - inserts[start] += ' ('; - } - else { - inserts[start] = '('; - } - inserts[end] = ')'; - } - for (i = start + 1; i < end; i += 1) { - inserts[i] = '|'; - } - } - } - }); - - // collect all actions format strings - var parts = []; - - actions.forEach(function (action, actionIndex) { - var part; - var optionString; - var argsDefault; - var argsString; - - // suppressed arguments are marked with None - // remove | separators for suppressed arguments - if (action.help === $$.SUPPRESS) { - parts.push(null); - if (inserts[actionIndex] === '|') { - inserts.splice(actionIndex, actionIndex); - } else if (inserts[actionIndex + 1] === '|') { - inserts.splice(actionIndex + 1, actionIndex + 1); - } - - // produce all arg strings - } else if (!action.isOptional()) { - part = self._formatArgs(action, action.dest); - - // if it's in a group, strip the outer [] - if (groupActions.indexOf(action) >= 0) { - if (part[0] === '[' && part[part.length - 1] === ']') { - part = part.slice(1, -1); - } - } - // add the action string to the list - parts.push(part); - - // produce the first way to invoke the option in brackets - } else { - optionString = action.optionStrings[0]; - - // if the Optional doesn't take a value, format is: -s or --long - if (action.nargs === 0) { - part = '' + optionString; - - // if the Optional takes a value, format is: -s ARGS or --long ARGS - } else { - argsDefault = action.dest.toUpperCase(); - argsString = self._formatArgs(action, argsDefault); - part = optionString + ' ' + argsString; - } - // make it look optional if it's not required or in a group - if (!action.required && groupActions.indexOf(action) < 0) { - part = '[' + part + ']'; - } - // add the action string to the list - parts.push(part); - } - }); - - // insert things at the necessary indices - for (var i = inserts.length - 1; i >= 0; --i) { - if (inserts[i] !== null) { - parts.splice(i, 0, inserts[i]); - } - } - - // join all the action items with spaces - var text = parts.filter(function (part) { - return !!part; - }).join(' '); - - // clean up separators for mutually exclusive groups - text = text.replace(/([\[(]) /g, '$1'); // remove spaces - text = text.replace(/ ([\])])/g, '$1'); - text = text.replace(/\[ *\]/g, ''); // remove empty groups - text = text.replace(/\( *\)/g, ''); - text = text.replace(/\(([^|]*)\)/g, '$1'); // remove () from single action groups - - text = _.str.strip(text); - - // return the text - return text; -}; - -HelpFormatter.prototype._formatText = function (text) { - text = _.str.sprintf(text, {prog: this._prog}); - var textWidth = this._width - this._currentIndent; - var indentIncriment = _.str.repeat(' ', this._currentIndent); - return this._fillText(text, textWidth, indentIncriment) + $$.EOL + $$.EOL; -}; - -HelpFormatter.prototype._formatAction = function (action) { - var self = this; - - var helpText; - var helpLines; - var parts; - var indentFirst; - - // determine the required width and the entry label - var helpPosition = Math.min(this._actionMaxLength + 2, this._maxHelpPosition); - var helpWidth = this._width - helpPosition; - var actionWidth = helpPosition - this._currentIndent - 2; - var actionHeader = this._formatActionInvocation(action); - - // no help; start on same line and add a final newline - if (!action.help) { - actionHeader = _.str.repeat(' ', this._currentIndent) + actionHeader + $$.EOL; - - // short action name; start on the same line and pad two spaces - } else if (actionHeader.length <= actionWidth) { - actionHeader = _.str.repeat(' ', this._currentIndent) + - actionHeader + - ' ' + - _.str.repeat(' ', actionWidth - actionHeader.length); - indentFirst = 0; - - // long action name; start on the next line - } else { - actionHeader = _.str.repeat(' ', this._currentIndent) + actionHeader + $$.EOL; - indentFirst = helpPosition; - } - - // collect the pieces of the action help - parts = [actionHeader]; - - // if there was help for the action, add lines of help text - if (!!action.help) { - helpText = this._expandHelp(action); - helpLines = this._splitLines(helpText, helpWidth); - parts.push(_.str.repeat(' ', indentFirst) + helpLines[0] + $$.EOL); - helpLines.slice(1).forEach(function (line) { - parts.push(_.str.repeat(' ', helpPosition) + line + $$.EOL); - }); - - // or add a newline if the description doesn't end with one - } else if (actionHeader.charAt(actionHeader.length - 1) !== $$.EOL) { - parts.push($$.EOL); - } - // if there are any sub-actions, add their help as well - if (!!action._getSubactions) { - this._indent(); - action._getSubactions().forEach(function (subaction) { - parts.push(self._formatAction(subaction)); - }); - this._dedent(); - } - // return a single string - return this._joinParts(parts); -}; - -HelpFormatter.prototype._formatActionInvocation = function (action) { - if (!action.isOptional()) { - var format_func = this._metavarFormatter(action, action.dest); - var metavars = format_func(1); - return metavars[0]; - } else { - var parts = []; - var argsDefault; - var argsString; - - // if the Optional doesn't take a value, format is: -s, --long - if (action.nargs === 0) { - parts = parts.concat(action.optionStrings); - - // if the Optional takes a value, format is: -s ARGS, --long ARGS - } else { - argsDefault = action.dest.toUpperCase(); - argsString = this._formatArgs(action, argsDefault); - action.optionStrings.forEach(function (optionString) { - parts.push(optionString + ' ' + argsString); - }); - } - return parts.join(', '); - } -}; - -HelpFormatter.prototype._metavarFormatter = function (action, metavarDefault) { - var result; - - if (!!action.metavar || action.metavar === '') { - result = action.metavar; - } else if (!!action.choices) { - var choices = action.choices; - - if (_.isString(choices)) { - choices = choices.split('').join(', '); - } else if (_.isArray(choices)) { - choices = choices.join(','); - } - else - { - choices = _.keys(choices).join(','); - } - result = '{' + choices + '}'; - } else { - result = metavarDefault; - } - - return function (size) { - if (Array.isArray(result)) { - return result; - } else { - var metavars = []; - for (var i = 0; i < size; i += 1) { - metavars.push(result); - } - return metavars; - } - }; -}; - -HelpFormatter.prototype._formatArgs = function (action, metavarDefault) { - var result; - var metavars; - - var buildMetavar = this._metavarFormatter(action, metavarDefault); - - switch (action.nargs) { - case undefined: - case null: - metavars = buildMetavar(1); - result = '' + metavars[0]; - break; - case $$.OPTIONAL: - metavars = buildMetavar(1); - result = '[' + metavars[0] + ']'; - break; - case $$.ZERO_OR_MORE: - metavars = buildMetavar(2); - result = '[' + metavars[0] + ' [' + metavars[1] + ' ...]]'; - break; - case $$.ONE_OR_MORE: - metavars = buildMetavar(2); - result = '' + metavars[0] + ' [' + metavars[1] + ' ...]'; - break; - case $$.REMAINDER: - result = '...'; - break; - case $$.PARSER: - metavars = buildMetavar(1); - result = metavars[0] + ' ...'; - break; - default: - metavars = buildMetavar(action.nargs); - result = metavars.join(' '); - } - return result; -}; - -HelpFormatter.prototype._expandHelp = function (action) { - var actionProperty; - var actionValue; - - var params = {prog: this._prog}; - - for (actionProperty in action) { - if (action.hasOwnProperty(actionProperty)) { - actionValue = action[actionProperty]; - - if (actionValue !== $$.SUPPRESS) { - params[actionProperty] = actionValue; - } - } - } - - if (!!params.choices) { - if (_.isString(params.choices)) { - params.choices = params.choices.split('').join(', '); - } - else if (_.isArray(params.choices)) { - params.choices = params.choices.join(', '); - } - else { - params.choices = _.keys(params.choices).join(', '); - } - } - - return _.str.sprintf(this._getHelpString(action), params); -}; - -HelpFormatter.prototype._splitLines = function (text, width) { - var lines = []; - var delimiters = [" ", ".", ",", "!", "?"]; - var re = new RegExp('[' + delimiters.join('') + '][^' + delimiters.join('') + ']*$'); - - text = text.replace(/[\n\|\t]/g, ' '); - - text = _.str.strip(text); - text = text.replace(this._whitespaceMatcher, ' '); - - // Wraps the single paragraph in text (a string) so every line - // is at most width characters long. - text.split($$.EOL).forEach(function (line) { - if (width >= line.length) { - lines.push(line); - return; - } - - var wrapStart = 0; - var wrapEnd = width; - var delimiterIndex = 0; - while (wrapEnd <= line.length) { - if (wrapEnd !== line.length && delimiters.indexOf(line[wrapEnd] < -1)) { - delimiterIndex = (re.exec(line.substring(wrapStart, wrapEnd)) || {}).index; - wrapEnd = wrapStart + delimiterIndex + 1; - } - lines.push(line.substring(wrapStart, wrapEnd)); - wrapStart = wrapEnd; - wrapEnd += width; - } - if (wrapStart < line.length) { - lines.push(line.substring(wrapStart, wrapEnd)); - } - }); - - return lines; -}; - -HelpFormatter.prototype._fillText = function (text, width, indent) { - var lines = this._splitLines(text, width); - lines = lines.map(function (line) { - return indent + line; - }); - return lines.join($$.EOL); -}; - -HelpFormatter.prototype._getHelpString = function (action) { - return action.help; -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/namespace.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/namespace.js deleted file mode 100644 index 3546f2da..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/lib/namespace.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * class Namespace - * - * Simple object for storing attributes. Implements equality by attribute names - * and values, and provides a simple string representation. - * - * See also [original guide][1] - * - * [1]:http://docs.python.org/dev/library/argparse.html#the-namespace-object - **/ -'use strict'; - -var _ = require('underscore'); - -/** - * new Namespace(options) - * - options(object): predefined propertis for result object - * - **/ -var Namespace = module.exports = function Namespace(options) { - _.extend(this, options); -}; - -/** - * Namespace#isset(key) -> Boolean - * - key (string|number): property name - * - * Tells whenever `namespace` contains given `key` or not. - **/ -Namespace.prototype.isset = function (key) { - return _.has(this, key); -}; - -/** - * Namespace#set(key, value) -> self - * -key (string|number|object): propery name - * -value (mixed): new property value - * - * Set the property named key with value. - * If key object then set all key properties to namespace object - **/ -Namespace.prototype.set = function (key, value) { - if (typeof (key) === 'object') { - _.extend(this, key); - } else { - this[key] = value; - } - return this; -}; - -/** - * Namespace#get(key, defaultValue) -> mixed - * - key (string|number): property name - * - defaultValue (mixed): default value - * - * Return the property key or defaulValue if not set - **/ -Namespace.prototype.get = function (key, defaultValue) { - return !this[key] ? defaultValue: this[key]; -}; - -/** - * Namespace#unset(key, defaultValue) -> mixed - * - key (string|number): property name - * - defaultValue (mixed): default value - * - * Return data[key](and delete it) or defaultValue - **/ -Namespace.prototype.unset = function (key, defaultValue) { - var value = this[key]; - if (value !== null) { - delete this[key]; - return value; - } else { - return defaultValue; - } -}; diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/.travis.yml b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/.travis.yml deleted file mode 100644 index ab27b29b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: ruby -rvm: - - 1.9.3 - -before_script: - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - - sleep 2 \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile deleted file mode 100644 index aed29c3c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -gem 'uglifier' -gem 'rake' diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile.lock b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile.lock deleted file mode 100644 index 2c52be46..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Gemfile.lock +++ /dev/null @@ -1,17 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - execjs (1.4.0) - multi_json (~> 1.0) - multi_json (1.3.6) - rake (0.9.2.2) - uglifier (1.3.0) - execjs (>= 0.3.0) - multi_json (~> 1.0, >= 1.0.2) - -PLATFORMS - ruby - -DEPENDENCIES - rake - uglifier diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/README.markdown b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/README.markdown deleted file mode 100644 index 1a39ad96..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/README.markdown +++ /dev/null @@ -1,814 +0,0 @@ -# Underscore.string [![Build Status](https://secure.travis-ci.org/epeli/underscore.string.png?branch=master)](http://travis-ci.org/epeli/underscore.string) # - - - -Javascript lacks complete string manipulation operations. -This an attempt to fill that gap. List of build-in methods can be found -for example from [Dive Into JavaScript][d]. - -[d]: http://www.diveintojavascript.com/core-javascript-reference/the-string-object - - -As name states this an extension for [Underscore.js][u], but it can be used -independently from **_s**-global variable. But with Underscore.js you can -use Object-Oriented style and chaining: - -[u]: http://documentcloud.github.com/underscore/ - -```javascript -_(" epeli ").chain().trim().capitalize().value() -=> "Epeli" -``` - -## Download ## - - * [Development version](https://raw.github.com/epeli/underscore.string/master/lib/underscore.string.js) *Uncompressed with Comments 18kb* - * [Production version](https://github.com/epeli/underscore.string/raw/master/dist/underscore.string.min.js) *Minified 7kb* - - -## Node.js installation ## - -**npm package** - - npm install underscore.string - -**Standalone usage**: - -```javascript -var _s = require('underscore.string'); -``` - -**Integrate with Underscore.js**: - -```javascript -var _ = require('underscore'); - -// Import Underscore.string to separate object, because there are conflict functions (include, reverse, contains) -_.str = require('underscore.string'); - -// Mix in non-conflict functions to Underscore namespace if you want -_.mixin(_.str.exports()); - -// All functions, include conflict, will be available through _.str object -_.str.include('Underscore.string', 'string'); // => true -``` - -**Or Integrate with Underscore.js without module loading** - -Run the following expression after Underscore.js and Underscore.string are loaded -```javascript -// _.str becomes a global variable if no module loading is detected -// Mix in non-conflict functions to Underscore namespace -_.mixin(_.str.exports()); -``` - -## String Functions ## - -For availability of functions in this way you need to mix in Underscore.string functions: - -```javascript -_.mixin(_.string.exports()); -``` - -otherwise functions from examples will be available through _.string or _.str objects: - -```javascript -_.str.capitalize('epeli') -=> "Epeli" -``` - -**numberFormat** _.numberFormat(number, [ decimals=0, decimalSeparator='.', orderSeparator=',']) - -Formats the numbers. - -```javascript -_.numberFormat(1000, 2) -=> "1,000.00" - -_.numberFormat(123456789.123, 5, '.', ',') -=> "123,456,789.12300" -``` - - -**levenshtein** _.levenshtein(string1, string2) - -Calculates [Levenshtein distance][ld] between two strings. -[ld]: http://en.wikipedia.org/wiki/Levenshtein_distance - -```javascript -_.levenshtein('kitten', 'kittah') -=> 2 -``` - -**capitalize** _.capitalize(string) - -Converts first letter of the string to uppercase. - -```javascript -_.capitalize("foo Bar") -=> "Foo Bar" -``` - -**chop** _.chop(string, step) - -```javascript -_.chop('whitespace', 3) -=> ['whi','tes','pac','e'] -``` - -**clean** _.clean(str) - -Compress some whitespaces to one. - -```javascript -_.clean(" foo bar ") -=> 'foo bar' -``` - -**chars** _.chars(str) - -```javascript -_.chars('Hello') -=> ['H','e','l','l','o'] -``` - -**swapCase** _.swapCase(str) - -Returns a copy of the string in which all the case-based characters have had their case swapped. - -```javascript -_.swapCase('hELLO') -=> 'Hello' -``` - -**include** available only through _.str object, because Underscore has function with the same name. - -```javascript -_.str.include("foobar", "ob") -=> true -``` - -(removed) **includes** _.includes(string, substring) - -Tests if string contains a substring. - -```javascript -_.includes("foobar", "ob") -=> true -``` - -**includes** function was removed - -But you can create it in this way, for compatibility with previous versions: - -```javascript -_.includes = _.str.include -``` - -**count** _.count(string, substring) - -```javascript -_('Hello world').count('l') -=> 3 -``` - -**escapeHTML** _.escapeHTML(string) - -Converts HTML special characters to their entity equivalents. - -```javascript -_('
        Blah blah blah
        ').escapeHTML(); -=> '<div>Blah blah blah</div>' -``` - -**unescapeHTML** _.unescapeHTML(string) - -Converts entity characters to HTML equivalents. - -```javascript -_('<div>Blah blah blah</div>').unescapeHTML(); -=> '
        Blah blah blah
        ' -``` - -**insert** _.insert(string, index, substing) - -```javascript -_('Hello ').insert(6, 'world') -=> 'Hello world' -``` - -**isBlank** _.isBlank(string) - -```javascript -_('').isBlank(); // => true -_('\n').isBlank(); // => true -_(' ').isBlank(); // => true -_('a').isBlank(); // => false -``` - -**join** _.join(separator, *strings) - -Joins strings together with given separator - -```javascript -_.join(" ", "foo", "bar") -=> "foo bar" -``` - -**lines** _.lines(str) - -```javascript -_.lines("Hello\nWorld") -=> ["Hello", "World"] -``` - -**reverse** available only through _.str object, because Underscore has function with the same name. - -Return reversed string: - -```javascript -_.str.reverse("foobar") -=> 'raboof' -``` - -**splice** _.splice(string, index, howmany, substring) - -Like a array splice. - -```javascript -_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli') -=> 'https://edtsech@bitbucket.org/epeli/underscore.strings' -``` - -**startsWith** _.startsWith(string, starts) - -This method checks whether string starts with starts. - -```javascript -_("image.gif").startsWith("image") -=> true -``` - -**endsWith** _.endsWith(string, ends) - -This method checks whether string ends with ends. - -```javascript -_("image.gif").endsWith("gif") -=> true -``` - -**succ** _.succ(str) - -Returns the successor to str. - -```javascript -_('a').succ() -=> 'b' - -_('A').succ() -=> 'B' -``` - -**supplant** - -Supplant function was removed, use Underscore.js [template function][p]. - -[p]: http://documentcloud.github.com/underscore/#template - -**strip** alias for *trim* - -**lstrip** alias for *ltrim* - -**rstrip** alias for *rtrim* - -**titleize** _.titleize(string) - -```javascript -_('my name is epeli').titleize() -=> 'My Name Is Epeli' -``` - -**camelize** _.camelize(string) - -Converts underscored or dasherized string to a camelized one - -```javascript -_('-moz-transform').camelize() -=> 'MozTransform' -``` - -**classify** _.classify(string) - -Converts string to camelized class name - -```javascript -_('some_class_name').classify() -=> 'SomeClassName' -``` - -**underscored** _.underscored(string) - -Converts a camelized or dasherized string into an underscored one - -```javascript -_('MozTransform').underscored() -=> 'moz_transform' -``` - -**dasherize** _.dasherize(string) - -Converts a underscored or camelized string into an dasherized one - -```javascript -_('MozTransform').dasherize() -=> '-moz-transform' -``` - -**humanize** _.humanize(string) - -Converts an underscored, camelized, or dasherized string into a humanized one. -Also removes beginning and ending whitespace, and removes the postfix '_id'. - -```javascript -_(' capitalize dash-CamelCase_underscore trim ').humanize() -=> 'Capitalize dash camel case underscore trim' -``` - -**trim** _.trim(string, [characters]) - -trims defined characters from begining and ending of the string. -Defaults to whitespace characters. - -```javascript -_.trim(" foobar ") -=> "foobar" - -_.trim("_-foobar-_", "_-") -=> "foobar" -``` - - -**ltrim** _.ltrim(string, [characters]) - -Left trim. Similar to trim, but only for left side. - - -**rtrim** _.rtrim(string, [characters]) - -Right trim. Similar to trim, but only for right side. - -**truncate** _.truncate(string, length, truncateString) - -```javascript -_('Hello world').truncate(5) -=> 'Hello...' - -_('Hello').truncate(10) -=> 'Hello' -``` - -**prune** _.prune(string, length, pruneString) - -Elegant version of truncate. -Makes sure the pruned string does not exceed the original length. -Avoid half-chopped words when truncating. - -```javascript -_('Hello, world').prune(5) -=> 'Hello...' - -_('Hello, world').prune(8) -=> 'Hello...' - -_('Hello, world').prune(5, ' (read a lot more)') -=> 'Hello, world' (as adding "(read a lot more)" would be longer than the original string) - -_('Hello, cruel world').prune(15) -=> 'Hello, cruel...' - -_('Hello').prune(10) -=> 'Hello' -``` - -**words** _.words(str, delimiter=/\s+/) - -Split string by delimiter (String or RegExp), /\s+/ by default. - -```javascript -_.words(" I love you ") -=> ["I","love","you"] - -_.words("I_love_you", "_") -=> ["I","love","you"] - -_.words("I-love-you", /-/) -=> ["I","love","you"] - -_.words(" ") -=> [] -``` - -**sprintf** _.sprintf(string format, *arguments) - -C like string formatting. -Credits goes to [Alexandru Marasteanu][o]. -For more detailed documentation, see the [original page][o]. - -[o]: http://www.diveintojavascript.com/projects/sprintf-for-javascript - -```javascript -_.sprintf("%.1f", 1.17) -"1.2" -``` - -**pad** _.pad(str, length, [padStr, type]) - -pads the `str` with characters until the total string length is equal to the passed `length` parameter. By default, pads on the **left** with the space char (`" "`). `padStr` is truncated to a single character if necessary. - -```javascript -_.pad("1", 8) --> " 1"; - -_.pad("1", 8, '0') --> "00000001"; - -_.pad("1", 8, '0', 'right') --> "10000000"; - -_.pad("1", 8, '0', 'both') --> "00001000"; - -_.pad("1", 8, 'bleepblorp', 'both') --> "bbbb1bbb"; -``` - -**lpad** _.lpad(str, length, [padStr]) - -left-pad a string. Alias for `pad(str, length, padStr, 'left')` - -```javascript -_.lpad("1", 8, '0') --> "00000001"; -``` - -**rpad** _.rpad(str, length, [padStr]) - -right-pad a string. Alias for `pad(str, length, padStr, 'right')` - -```javascript -_.rpad("1", 8, '0') --> "10000000"; -``` - -**lrpad** _.lrpad(str, length, [padStr]) - -left/right-pad a string. Alias for `pad(str, length, padStr, 'both')` - -```javascript -_.lrpad("1", 8, '0') --> "00001000"; -``` - -**center** alias for **lrpad** - -**ljust** alias for *rpad* - -**rjust** alias for *lpad* - -**toNumber** _.toNumber(string, [decimals]) - -Parse string to number. Returns NaN if string can't be parsed to number. - -```javascript -_('2.556').toNumber() -=> 3 - -_('2.556').toNumber(1) -=> 2.6 -``` - -**strRight** _.strRight(string, pattern) - -Searches a string from left to right for a pattern and returns a substring consisting of the characters in the string that are to the right of the pattern or all string if no match found. - -```javascript -_('This_is_a_test_string').strRight('_') -=> "is_a_test_string"; -``` - -**strRightBack** _.strRightBack(string, pattern) - -Searches a string from right to left for a pattern and returns a substring consisting of the characters in the string that are to the right of the pattern or all string if no match found. - -```javascript -_('This_is_a_test_string').strRightBack('_') -=> "string"; -``` - -**strLeft** _.strLeft(string, pattern) - -Searches a string from left to right for a pattern and returns a substring consisting of the characters in the string that are to the left of the pattern or all string if no match found. - -```javascript -_('This_is_a_test_string').strLeft('_') -=> "This"; -``` - -**strLeftBack** _.strLeftBack(string, pattern) - -Searches a string from right to left for a pattern and returns a substring consisting of the characters in the string that are to the left of the pattern or all string if no match found. - -```javascript -_('This_is_a_test_string').strLeftBack('_') -=> "This_is_a_test"; -``` - -**stripTags** - -Removes all html tags from string. - -```javascript -_('a link').stripTags() -=> 'a link' - -_('a link').stripTags() -=> 'a linkalert("hello world!")' -``` - -**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) - -Join an array into a human readable sentence. - -```javascript -_.toSentence(['jQuery', 'Mootools', 'Prototype']) -=> 'jQuery, Mootools and Prototype'; - -_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') -=> 'jQuery, Mootools unt Prototype'; -``` - -**toSentenceSerial** _.toSentenceSerial(array, [delimiter, lastDelimiter]) - -The same as `toSentence`, but adjusts delimeters to use [Serial comma](http://en.wikipedia.org/wiki/Serial_comma). - -```javascript -_.toSentenceSerial(['jQuery', 'Mootools']) -=> 'jQuery and Mootools'; - -_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype']) -=> 'jQuery, Mootools, and Prototype' - -_.toSentenceSerial(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt '); -=> 'jQuery, Mootools, unt Prototype'; -``` - -**repeat** _.repeat(string, count, [separator]) - -Repeats a string count times. - -```javascript -_.repeat("foo", 3) -=> 'foofoofoo'; - -_.repeat("foo", 3, "bar") -=> 'foobarfoobarfoo' -``` - -**surround** _.surround(string, wrap) - -Surround a string with another string. - -```javascript -_.surround("foo", "ab") -=> 'abfooab'; -``` - -**quote** _.quote(string, quoteChar) or _.q(string, quoteChar) - -Quotes a string. `quoteChar` defaults to `"`. - -```javascript -_.quote('foo', quoteChar) -=> '"foo"'; -``` -**unquote** _.unquote(string, quoteChar) - -Unquotes a string. `quoteChar` defaults to `"`. - -```javascript -_.unquote('"foo"') -=> 'foo'; -_.unquote("'foo'", "'") -=> 'foo'; -``` - - -**slugify** _.slugify(string) - -Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. - -```javascript -_.slugify("Un éléphant à l'orée du bois") -=> 'un-elephant-a-loree-du-bois'; -``` - -***Caution: this function is charset dependent*** - -**naturalCmp** array.sort(_.naturalCmp) - -Naturally sort strings like humans would do. - -```javascript -['foo20', 'foo5'].sort(_.naturalCmp) -=> [ 'foo5', 'foo20' ] -``` - -**toBoolean** _.toBoolean(string) or _.toBool(string) - -Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive. - -```javascript -_.toBoolean("true") -=> true -_.toBoolean("FALSE") -=> false -_.toBoolean("random") -=> undefined -``` - -It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects. - -```javascript -_.toBoolean("truthy", ["truthy"], ["falsy"]) -=> true -_.toBoolean("true only at start", [/^true/]) -=> true -``` - -## Roadmap ## - -Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. - -#### Problems - -We lose two things for `include` and `reverse` methods from `_.string`: - -* Calls like `_('foobar').include('bar')` aren't available; -* Chaining isn't available too. - -But if you need this functionality you can create aliases for conflict functions which will be convenient for you: - -```javascript -_.mixin({ - includeString: _.str.include, - reverseString: _.str.reverse -}) - -// Now wrapper calls and chaining are available. -_('foobar').chain().reverseString().includeString('rab').value() -``` - -#### Standalone Usage - -If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias -But of course you can just reassign `_` variable with `_.string` - -```javascript -_ = _.string -``` - -## Changelog ## - -### 2.3.3 ### - -* Add `toBoolean` -* Add `unquote` -* Add quote char option to `quote` -* Support dash-separated words in `titleize` - -### 2.3.2 ### - -* Add `naturalCmp` -* Bug fix to `camelize` -* Add ă, ș, ț and ś to `slugify` -* Doc updates -* Add support for [component](http://component.io/) -* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.1...v2.3.2) - -### 2.3.1 ### - -* Bug fixes to `escapeHTML`, `classify`, `substr` -* Faster `count` -* Documentation fixes -* [Full changelog](https://github.com/epeli/underscore.string/compare/v2.3.0...v2.3.1) - -### 2.3.0 ### - -* Added `numberformat` method -* Added `levenshtein` method (Levenshtein distance calculation) -* Added `swapCase` method -* Changed default behavior of `words` method -* Added `toSentenceSerial` method -* Added `surround` and `quote` methods - -### 2.2.1 ### - -* Same as 2.2.0 (2.2.0rc on npm) to fix some npm drama - -### 2.2.0 ### - -* Capitalize method behavior changed -* Various perfomance tweaks - -### 2.1.1### - -* Fixed words method bug -* Added classify method - -### 2.1.0 ### - -* AMD support -* Added toSentence method -* Added slugify method -* Lots of speed optimizations - -### 2.0.0 ### - -* Added prune, humanize functions -* Added _.string (_.str) namespace for Underscore.string library -* Removed includes function - -For upgrading to this version you need to mix in Underscore.string library to Underscore object: - -```javascript -_.mixin(_.string.exports()); -``` - -and all non-conflict Underscore.string functions will be available through Underscore object. -Also function `includes` has been removed, you should replace this function by `_.str.include` -or create alias `_.includes = _.str.include` and all your code will work fine. - -### 1.1.6 ### - -* Fixed reverse and truncate -* Added isBlank, stripTags, inlude(alias for includes) -* Added uglifier compression - -### 1.1.5 ### - -* Added strRight, strRightBack, strLeft, strLeftBack - -### 1.1.4 ### - -* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust -* Integration with Underscore 1.1.6 - -### 1.1.3 ### - -* Added methods: underscored, camelize, dasherize -* Support newer version of npm - -### 1.1.2 ### - -* Created functions: lines, chars, words functions - -### 1.0.2 ### - -* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) -* Removed 'reverse' function, because this function override underscore.js 'reverse' - -## Contribute ## - -* Fork & pull request. Don't forget about tests. -* If you planning add some feature please create issue before. - -Otherwise changes will be rejected. - -## Contributors list ## -[Can be found here](https://github.com/epeli/underscore.string/graphs/contributors). - - -## Licence ## - -The MIT License - -Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org - -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/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Rakefile b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Rakefile deleted file mode 100644 index 2cd9eed9..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/Rakefile +++ /dev/null @@ -1,23 +0,0 @@ -# encoding: utf-8 -task default: :test - -desc 'Use UglifyJS to compress Underscore.string' -task :build do - require 'uglifier' - source = File.read('lib/underscore.string.js', :encoding => 'utf-8') - compressed = Uglifier.compile(source, copyright: false) - File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed } - compression_rate = compressed.length.to_f/source.length - puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%" -end - -desc 'Run tests' -task :test do - puts "Running underscore.string test suite." - result1 = system %{phantomjs ./test/run-qunit.js "test/test.html"} - - puts "Running Underscore test suite." - result2 = system %{phantomjs ./test/run-qunit.js "test/test_underscore/index.html"} - - exit(result1 && result2 ? 0 : 1) -end diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/component.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/component.json deleted file mode 100644 index ae91b65b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/component.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "underscore.string", - "repo": "epeli/underscore.string", - "description": "String manipulation extensions for Underscore.js javascript library", - "version": "2.3.3", - "keywords": ["underscore", "string"], - "dependencies": {}, - "development": {}, - "main": "lib/underscore.string.js", - "scripts": ["lib/underscore.string.js"] -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/dist/underscore.string.min.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/dist/underscore.string.min.js deleted file mode 100644 index 4f6b2b93..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/dist/underscore.string.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,n){"use strict";function r(e,n){var r,t,u=e.toLowerCase();for(n=[].concat(n),r=0;n.length>r;r+=1)if(t=n[r]){if(t.test&&t.test(e))return!0;if(t.toLowerCase()===u)return!0}}var t=n.prototype.trim,u=n.prototype.trimRight,i=n.prototype.trimLeft,l=function(e){return 1*e||0},o=function(e,n){if(1>n)return"";for(var r="";n>0;)1&n&&(r+=e),n>>=1,e+=e;return r},a=[].slice,c=function(e){return null==e?"\\s":e.source?e.source:"["+g.escapeRegExp(e)+"]"},s={lt:"<",gt:">",quot:'"',amp:"&",apos:"'"},f={};for(var p in s)f[s[p]]=p;f["'"]="#39";var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var r=o,t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};return t.format=function(t,u){var i,l,o,a,c,s,f,p=1,g=t.length,d="",m=[];for(l=0;g>l;l++)if(d=e(t[l]),"string"===d)m.push(t[l]);else if("array"===d){if(a=t[l],a[2])for(i=u[p],o=0;a[2].length>o;o++){if(!i.hasOwnProperty(a[2][o]))throw new Error(h('[_.sprintf] property "%s" does not exist',a[2][o]));i=i[a[2][o]]}else i=a[1]?u[a[1]]:u[p++];if(/[^s]/.test(a[8])&&"number"!=e(i))throw new Error(h("[_.sprintf] expecting number but found %s",e(i)));switch(a[8]){case"b":i=i.toString(2);break;case"c":i=n.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=a[7]?i.toExponential(a[7]):i.toExponential();break;case"f":i=a[7]?parseFloat(i).toFixed(a[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=n(i))&&a[7]?i.substring(0,a[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(a[8])&&a[3]&&i>=0?"+"+i:i,s=a[4]?"0"==a[4]?"0":a[4].charAt(1):" ",f=a[6]-n(i).length,c=a[6]?r(s,f):"",m.push(a[5]?i+c:c+i)}return m.join("")},t.cache={},t.parse=function(e){for(var n=e,r=[],t=[],u=0;n;){if(null!==(r=/^[^\x25]+/.exec(n)))t.push(r[0]);else if(null!==(r=/^\x25{2}/.exec(n)))t.push("%");else{if(null===(r=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(n)))throw new Error("[_.sprintf] huh?");if(r[2]){u|=1;var i=[],l=r[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(l)))throw new Error("[_.sprintf] huh?");for(i.push(o[1]);""!==(l=l.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(l)))i.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(l)))throw new Error("[_.sprintf] huh?");i.push(o[1])}r[2]=i}else u|=2;if(3===u)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");t.push(r)}n=n.substring(r[0].length)}return t},t}(),g={VERSION:"2.3.0",isBlank:function(e){return null==e&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return null==e?"":n(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=null==e?"":n(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,r){return null==e?[]:(e=n(e),r=~~r,r>0?e.match(new RegExp(".{1,"+r+"}","g")):[e])},clean:function(e){return g.strip(e).replace(/\s+/g," ")},count:function(e,r){if(null==e||null==r)return 0;e=n(e),r=n(r);for(var t=0,u=0,i=r.length;;){if(u=e.indexOf(r,u),-1===u)break;t++,u+=i}return t},chars:function(e){return null==e?[]:n(e).split("")},swapCase:function(e){return null==e?"":n(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return null==e?"":n(e).replace(/[&<>"']/g,function(e){return"&"+f[e]+";"})},unescapeHTML:function(e){return null==e?"":n(e).replace(/\&([^;]+);/g,function(e,r){var t;return r in s?s[r]:(t=r.match(/^#x([\da-fA-F]+)$/))?n.fromCharCode(parseInt(t[1],16)):(t=r.match(/^#(\d+)$/))?n.fromCharCode(~~t[1]):e})},escapeRegExp:function(e){return null==e?"":n(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,n,r,t){var u=g.chars(e);return u.splice(~~n,~~r,t),u.join("")},insert:function(e,n,r){return g.splice(e,n,0,r)},include:function(e,r){return""===r?!0:null==e?!1:-1!==n(e).indexOf(r)},join:function(){var e=a.call(arguments),n=e.shift();return null==n&&(n=""),e.join(n)},lines:function(e){return null==e?[]:n(e).split("\n")},reverse:function(e){return g.chars(e).reverse().join("")},startsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(0,r.length)===r)},endsWith:function(e,r){return""===r?!0:null==e||null==r?!1:(e=n(e),r=n(r),e.length>=r.length&&e.slice(e.length-r.length)===r)},succ:function(e){return null==e?"":(e=n(e),e.slice(0,-1)+n.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return null==e?"":(e=n(e).toLowerCase(),e.replace(/(?:^|\s|-)\S/g,function(e){return e.toUpperCase()}))},camelize:function(e){return g.trim(e).replace(/[-_\s]+(.)?/g,function(e,n){return n?n.toUpperCase():""})},underscored:function(e){return g.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return g.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return g.titleize(n(e).replace(/[\W_]/g," ")).replace(/\s/g,"")},humanize:function(e){return g.capitalize(g.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return null==e?"":!r&&t?t.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,r){return null==e?"":!r&&i?i.call(e):(r=c(r),n(e).replace(new RegExp("^"+r+"+"),""))},rtrim:function(e,r){return null==e?"":!r&&u?u.call(e):(r=c(r),n(e).replace(new RegExp(r+"+$"),""))},truncate:function(e,r,t){return null==e?"":(e=n(e),t=t||"...",r=~~r,e.length>r?e.slice(0,r)+t:e)},prune:function(e,r,t){if(null==e)return"";if(e=n(e),r=~~r,t=null!=t?n(t):"...",r>=e.length)return e;var u=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},i=e.slice(0,r+1).replace(/.(?=\W*\w*$)/g,u);return i=i.slice(i.length-2).match(/\w\w/)?i.replace(/\s*\S+$/,""):g.rtrim(i.slice(0,i.length-1)),(i+t).length>e.length?e:e.slice(0,i.length)+t},words:function(e,n){return g.isBlank(e)?[]:g.trim(e,n).split(n||/\s+/)},pad:function(e,r,t,u){e=null==e?"":n(e),r=~~r;var i=0;switch(t?t.length>1&&(t=t.charAt(0)):t=" ",u){case"right":return i=r-e.length,e+o(t,i);case"both":return i=r-e.length,o(t,Math.ceil(i/2))+e+o(t,Math.floor(i/2));default:return i=r-e.length,o(t,i)+e}},lpad:function(e,n,r){return g.pad(e,n,r)},rpad:function(e,n,r){return g.pad(e,n,r,"right")},lrpad:function(e,n,r){return g.pad(e,n,r,"both")},sprintf:h,vsprintf:function(e,n){return n.unshift(e),h.apply(null,n)},toNumber:function(e,n){return e?(e=g.trim(e),e.match(/^-?\d+(?:\.\d+)?$/)?l(l(e).toFixed(~~n)):0/0):0},numberFormat:function(e,n,r,t){if(isNaN(e)||null==e)return"";e=e.toFixed(~~n),t="string"==typeof t?t:",";var u=e.split("."),i=u[0],l=u[1]?(r||".")+u[1]:"";return i.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+t)+l},strRight:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strRightBack:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.lastIndexOf(r):-1;return~t?e.slice(t+r.length,e.length):e},strLeft:function(e,r){if(null==e)return"";e=n(e),r=null!=r?n(r):r;var t=r?e.indexOf(r):-1;return~t?e.slice(0,t):e},strLeftBack:function(e,n){if(null==e)return"";e+="",n=null!=n?""+n:n;var r=e.lastIndexOf(n);return~r?e.slice(0,r):e},toSentence:function(e,n,r,t){n=n||", ",r=r||" and ";var u=e.slice(),i=u.pop();return e.length>2&&t&&(r=g.rtrim(n)+r),u.length?u.join(n)+r+i:i},toSentenceSerial:function(){var e=a.call(arguments);return e[3]=!0,g.toSentence.apply(g,e)},slugify:function(e){if(null==e)return"";var r="ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź",t="aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz",u=new RegExp(c(r),"g");return e=n(e).toLowerCase().replace(u,function(e){var n=r.indexOf(e);return t.charAt(n)||"-"}),g.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,n){return[n,e,n].join("")},quote:function(e,n){return g.surround(e,n||'"')},unquote:function(e,n){return n=n||'"',e[0]===n&&e[e.length-1]===n?e.slice(1,e.length-1):e},exports:function(){var e={};for(var n in this)this.hasOwnProperty(n)&&!n.match(/^(?:include|contains|reverse)$/)&&(e[n]=this[n]);return e},repeat:function(e,r,t){if(null==e)return"";if(r=~~r,null==t)return o(n(e),r);for(var u=[];r>0;u[--r]=e);return u.join(t)},naturalCmp:function(e,r){if(e==r)return 0;if(!e)return-1;if(!r)return 1;for(var t=/(\.\d+)|(\d+)|(\D+)/g,u=n(e).toLowerCase().match(t),i=n(r).toLowerCase().match(t),l=Math.min(u.length,i.length),o=0;l>o;o++){var a=u[o],c=i[o];if(a!==c){var s=parseInt(a,10);if(!isNaN(s)){var f=parseInt(c,10);if(!isNaN(f)&&s-f)return s-f}return c>a?-1:1}}return u.length===i.length?u.length-i.length:r>e?-1:1},levenshtein:function(e,r){if(null==e&&null==r)return 0;if(null==e)return n(r).length;if(null==r)return n(e).length;e=n(e),r=n(r);for(var t,u,i=[],l=0;r.length>=l;l++)for(var o=0;e.length>=o;o++)u=l&&o?e.charAt(o-1)===r.charAt(l-1)?t:Math.min(i[o],i[o-1],t)+1:l+o,t=i[o],i[o]=u;return i.pop()},toBoolean:function(e,n,t){return"number"==typeof e&&(e=""+e),"string"!=typeof e?!!e:(e=g.trim(e),r(e,n||["true","1"])?!0:r(e,t||["false","0"])?!1:void 0)}};g.strip=g.trim,g.lstrip=g.ltrim,g.rstrip=g.rtrim,g.center=g.lrpad,g.rjust=g.lpad,g.ljust=g.rpad,g.contains=g.include,g.q=g.quote,g.toBool=g.toBoolean,"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(module.exports=g),exports._s=g),"function"==typeof define&&define.amd&&define("underscore.string",[],function(){return g}),e._=e._||{},e._.string=e._.str=g}(this,String); \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js deleted file mode 100644 index 87611173..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js +++ /dev/null @@ -1,673 +0,0 @@ -// Underscore.string -// (c) 2010 Esa-Matti Suuronen -// Underscore.string is freely distributable under the terms of the MIT license. -// Documentation: https://github.com/epeli/underscore.string -// Some code is borrowed from MooTools and Alexandru Marasteanu. -// Version '2.3.2' - -!function(root, String){ - 'use strict'; - - // Defining helper functions. - - var nativeTrim = String.prototype.trim; - var nativeTrimRight = String.prototype.trimRight; - var nativeTrimLeft = String.prototype.trimLeft; - - var parseNumber = function(source) { return source * 1 || 0; }; - - var strRepeat = function(str, qty){ - if (qty < 1) return ''; - var result = ''; - while (qty > 0) { - if (qty & 1) result += str; - qty >>= 1, str += str; - } - return result; - }; - - var slice = [].slice; - - var defaultToWhiteSpace = function(characters) { - if (characters == null) - return '\\s'; - else if (characters.source) - return characters.source; - else - return '[' + _s.escapeRegExp(characters) + ']'; - }; - - // Helper for toBoolean - function boolMatch(s, matchers) { - var i, matcher, down = s.toLowerCase(); - matchers = [].concat(matchers); - for (i = 0; i < matchers.length; i += 1) { - matcher = matchers[i]; - if (!matcher) continue; - if (matcher.test && matcher.test(s)) return true; - if (matcher.toLowerCase() === down) return true; - } - } - - var escapeChars = { - lt: '<', - gt: '>', - quot: '"', - amp: '&', - apos: "'" - }; - - var reversedEscapeChars = {}; - for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key; - reversedEscapeChars["'"] = '#39'; - - // sprintf() for JavaScript 0.7-beta1 - // http://www.diveintojavascript.com/projects/javascript-sprintf - // - // Copyright (c) Alexandru Marasteanu - // All rights reserved. - - var sprintf = (function() { - function get_type(variable) { - return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); - } - - var str_repeat = strRepeat; - - var str_format = function() { - if (!str_format.cache.hasOwnProperty(arguments[0])) { - str_format.cache[arguments[0]] = str_format.parse(arguments[0]); - } - return str_format.format.call(null, str_format.cache[arguments[0]], arguments); - }; - - str_format.format = function(parse_tree, argv) { - var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; - for (i = 0; i < tree_length; i++) { - node_type = get_type(parse_tree[i]); - if (node_type === 'string') { - output.push(parse_tree[i]); - } - else if (node_type === 'array') { - match = parse_tree[i]; // convenience purposes only - if (match[2]) { // keyword argument - arg = argv[cursor]; - for (k = 0; k < match[2].length; k++) { - if (!arg.hasOwnProperty(match[2][k])) { - throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); - } - arg = arg[match[2][k]]; - } - } else if (match[1]) { // positional argument (explicit) - arg = argv[match[1]]; - } - else { // positional argument (implicit) - arg = argv[cursor++]; - } - - if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { - throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); - } - switch (match[8]) { - case 'b': arg = arg.toString(2); break; - case 'c': arg = String.fromCharCode(arg); break; - case 'd': arg = parseInt(arg, 10); break; - case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; - case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; - case 'o': arg = arg.toString(8); break; - case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; - case 'u': arg = Math.abs(arg); break; - case 'x': arg = arg.toString(16); break; - case 'X': arg = arg.toString(16).toUpperCase(); break; - } - arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); - pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; - pad_length = match[6] - String(arg).length; - pad = match[6] ? str_repeat(pad_character, pad_length) : ''; - output.push(match[5] ? arg + pad : pad + arg); - } - } - return output.join(''); - }; - - str_format.cache = {}; - - str_format.parse = function(fmt) { - var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; - while (_fmt) { - if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { - parse_tree.push(match[0]); - } - else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { - parse_tree.push('%'); - } - else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { - if (match[2]) { - arg_names |= 1; - var field_list = [], replacement_field = match[2], field_match = []; - if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { - if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else { - throw new Error('[_.sprintf] huh?'); - } - } - } - else { - throw new Error('[_.sprintf] huh?'); - } - match[2] = field_list; - } - else { - arg_names |= 2; - } - if (arg_names === 3) { - throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); - } - parse_tree.push(match); - } - else { - throw new Error('[_.sprintf] huh?'); - } - _fmt = _fmt.substring(match[0].length); - } - return parse_tree; - }; - - return str_format; - })(); - - - - // Defining underscore.string - - var _s = { - - VERSION: '2.3.0', - - isBlank: function(str){ - if (str == null) str = ''; - return (/^\s*$/).test(str); - }, - - stripTags: function(str){ - if (str == null) return ''; - return String(str).replace(/<\/?[^>]+>/g, ''); - }, - - capitalize : function(str){ - str = str == null ? '' : String(str); - return str.charAt(0).toUpperCase() + str.slice(1); - }, - - chop: function(str, step){ - if (str == null) return []; - str = String(str); - step = ~~step; - return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str]; - }, - - clean: function(str){ - return _s.strip(str).replace(/\s+/g, ' '); - }, - - count: function(str, substr){ - if (str == null || substr == null) return 0; - - str = String(str); - substr = String(substr); - - var count = 0, - pos = 0, - length = substr.length; - - while (true) { - pos = str.indexOf(substr, pos); - if (pos === -1) break; - count++; - pos += length; - } - - return count; - }, - - chars: function(str) { - if (str == null) return []; - return String(str).split(''); - }, - - swapCase: function(str) { - if (str == null) return ''; - return String(str).replace(/\S/g, function(c){ - return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase(); - }); - }, - - escapeHTML: function(str) { - if (str == null) return ''; - return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; }); - }, - - unescapeHTML: function(str) { - if (str == null) return ''; - return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){ - var match; - - if (entityCode in escapeChars) { - return escapeChars[entityCode]; - } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { - return String.fromCharCode(parseInt(match[1], 16)); - } else if (match = entityCode.match(/^#(\d+)$/)) { - return String.fromCharCode(~~match[1]); - } else { - return entity; - } - }); - }, - - escapeRegExp: function(str){ - if (str == null) return ''; - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); - }, - - splice: function(str, i, howmany, substr){ - var arr = _s.chars(str); - arr.splice(~~i, ~~howmany, substr); - return arr.join(''); - }, - - insert: function(str, i, substr){ - return _s.splice(str, i, 0, substr); - }, - - include: function(str, needle){ - if (needle === '') return true; - if (str == null) return false; - return String(str).indexOf(needle) !== -1; - }, - - join: function() { - var args = slice.call(arguments), - separator = args.shift(); - - if (separator == null) separator = ''; - - return args.join(separator); - }, - - lines: function(str) { - if (str == null) return []; - return String(str).split("\n"); - }, - - reverse: function(str){ - return _s.chars(str).reverse().join(''); - }, - - startsWith: function(str, starts){ - if (starts === '') return true; - if (str == null || starts == null) return false; - str = String(str); starts = String(starts); - return str.length >= starts.length && str.slice(0, starts.length) === starts; - }, - - endsWith: function(str, ends){ - if (ends === '') return true; - if (str == null || ends == null) return false; - str = String(str); ends = String(ends); - return str.length >= ends.length && str.slice(str.length - ends.length) === ends; - }, - - succ: function(str){ - if (str == null) return ''; - str = String(str); - return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1); - }, - - titleize: function(str){ - if (str == null) return ''; - str = String(str).toLowerCase(); - return str.replace(/(?:^|\s|-)\S/g, function(c){ return c.toUpperCase(); }); - }, - - camelize: function(str){ - return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c ? c.toUpperCase() : ""; }); - }, - - underscored: function(str){ - return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); - }, - - dasherize: function(str){ - return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase(); - }, - - classify: function(str){ - return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, ''); - }, - - humanize: function(str){ - return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); - }, - - trim: function(str, characters){ - if (str == null) return ''; - if (!characters && nativeTrim) return nativeTrim.call(str); - characters = defaultToWhiteSpace(characters); - return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), ''); - }, - - ltrim: function(str, characters){ - if (str == null) return ''; - if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str); - characters = defaultToWhiteSpace(characters); - return String(str).replace(new RegExp('^' + characters + '+'), ''); - }, - - rtrim: function(str, characters){ - if (str == null) return ''; - if (!characters && nativeTrimRight) return nativeTrimRight.call(str); - characters = defaultToWhiteSpace(characters); - return String(str).replace(new RegExp(characters + '+$'), ''); - }, - - truncate: function(str, length, truncateStr){ - if (str == null) return ''; - str = String(str); truncateStr = truncateStr || '...'; - length = ~~length; - return str.length > length ? str.slice(0, length) + truncateStr : str; - }, - - /** - * _s.prune: a more elegant version of truncate - * prune extra chars, never leaving a half-chopped word. - * @author github.com/rwz - */ - prune: function(str, length, pruneStr){ - if (str == null) return ''; - - str = String(str); length = ~~length; - pruneStr = pruneStr != null ? String(pruneStr) : '...'; - - if (str.length <= length) return str; - - var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, - template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' - - if (template.slice(template.length-2).match(/\w\w/)) - template = template.replace(/\s*\S+$/, ''); - else - template = _s.rtrim(template.slice(0, template.length-1)); - - return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr; - }, - - words: function(str, delimiter) { - if (_s.isBlank(str)) return []; - return _s.trim(str, delimiter).split(delimiter || /\s+/); - }, - - pad: function(str, length, padStr, type) { - str = str == null ? '' : String(str); - length = ~~length; - - var padlen = 0; - - if (!padStr) - padStr = ' '; - else if (padStr.length > 1) - padStr = padStr.charAt(0); - - switch(type) { - case 'right': - padlen = length - str.length; - return str + strRepeat(padStr, padlen); - case 'both': - padlen = length - str.length; - return strRepeat(padStr, Math.ceil(padlen/2)) + str - + strRepeat(padStr, Math.floor(padlen/2)); - default: // 'left' - padlen = length - str.length; - return strRepeat(padStr, padlen) + str; - } - }, - - lpad: function(str, length, padStr) { - return _s.pad(str, length, padStr); - }, - - rpad: function(str, length, padStr) { - return _s.pad(str, length, padStr, 'right'); - }, - - lrpad: function(str, length, padStr) { - return _s.pad(str, length, padStr, 'both'); - }, - - sprintf: sprintf, - - vsprintf: function(fmt, argv){ - argv.unshift(fmt); - return sprintf.apply(null, argv); - }, - - toNumber: function(str, decimals) { - if (!str) return 0; - str = _s.trim(str); - if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN; - return parseNumber(parseNumber(str).toFixed(~~decimals)); - }, - - numberFormat : function(number, dec, dsep, tsep) { - if (isNaN(number) || number == null) return ''; - - number = number.toFixed(~~dec); - tsep = typeof tsep == 'string' ? tsep : ','; - - var parts = number.split('.'), fnums = parts[0], - decimals = parts[1] ? (dsep || '.') + parts[1] : ''; - - return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals; - }, - - strRight: function(str, sep){ - if (str == null) return ''; - str = String(str); sep = sep != null ? String(sep) : sep; - var pos = !sep ? -1 : str.indexOf(sep); - return ~pos ? str.slice(pos+sep.length, str.length) : str; - }, - - strRightBack: function(str, sep){ - if (str == null) return ''; - str = String(str); sep = sep != null ? String(sep) : sep; - var pos = !sep ? -1 : str.lastIndexOf(sep); - return ~pos ? str.slice(pos+sep.length, str.length) : str; - }, - - strLeft: function(str, sep){ - if (str == null) return ''; - str = String(str); sep = sep != null ? String(sep) : sep; - var pos = !sep ? -1 : str.indexOf(sep); - return ~pos ? str.slice(0, pos) : str; - }, - - strLeftBack: function(str, sep){ - if (str == null) return ''; - str += ''; sep = sep != null ? ''+sep : sep; - var pos = str.lastIndexOf(sep); - return ~pos ? str.slice(0, pos) : str; - }, - - toSentence: function(array, separator, lastSeparator, serial) { - separator = separator || ', '; - lastSeparator = lastSeparator || ' and '; - var a = array.slice(), lastMember = a.pop(); - - if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator; - - return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember; - }, - - toSentenceSerial: function() { - var args = slice.call(arguments); - args[3] = true; - return _s.toSentence.apply(_s, args); - }, - - slugify: function(str) { - if (str == null) return ''; - - var from = "ąàáäâãåæăćęèéëêìíïîłńòóöôõøśșțùúüûñçżź", - to = "aaaaaaaaaceeeeeiiiilnoooooosstuuuunczz", - regex = new RegExp(defaultToWhiteSpace(from), 'g'); - - str = String(str).toLowerCase().replace(regex, function(c){ - var index = from.indexOf(c); - return to.charAt(index) || '-'; - }); - - return _s.dasherize(str.replace(/[^\w\s-]/g, '')); - }, - - surround: function(str, wrapper) { - return [wrapper, str, wrapper].join(''); - }, - - quote: function(str, quoteChar) { - return _s.surround(str, quoteChar || '"'); - }, - - unquote: function(str, quoteChar) { - quoteChar = quoteChar || '"'; - if (str[0] === quoteChar && str[str.length-1] === quoteChar) - return str.slice(1,str.length-1); - else return str; - }, - - exports: function() { - var result = {}; - - for (var prop in this) { - if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue; - result[prop] = this[prop]; - } - - return result; - }, - - repeat: function(str, qty, separator){ - if (str == null) return ''; - - qty = ~~qty; - - // using faster implementation if separator is not needed; - if (separator == null) return strRepeat(String(str), qty); - - // this one is about 300x slower in Google Chrome - for (var repeat = []; qty > 0; repeat[--qty] = str) {} - return repeat.join(separator); - }, - - naturalCmp: function(str1, str2){ - if (str1 == str2) return 0; - if (!str1) return -1; - if (!str2) return 1; - - var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g, - tokens1 = String(str1).toLowerCase().match(cmpRegex), - tokens2 = String(str2).toLowerCase().match(cmpRegex), - count = Math.min(tokens1.length, tokens2.length); - - for(var i = 0; i < count; i++) { - var a = tokens1[i], b = tokens2[i]; - - if (a !== b){ - var num1 = parseInt(a, 10); - if (!isNaN(num1)){ - var num2 = parseInt(b, 10); - if (!isNaN(num2) && num1 - num2) - return num1 - num2; - } - return a < b ? -1 : 1; - } - } - - if (tokens1.length === tokens2.length) - return tokens1.length - tokens2.length; - - return str1 < str2 ? -1 : 1; - }, - - levenshtein: function(str1, str2) { - if (str1 == null && str2 == null) return 0; - if (str1 == null) return String(str2).length; - if (str2 == null) return String(str1).length; - - str1 = String(str1); str2 = String(str2); - - var current = [], prev, value; - - for (var i = 0; i <= str2.length; i++) - for (var j = 0; j <= str1.length; j++) { - if (i && j) - if (str1.charAt(j - 1) === str2.charAt(i - 1)) - value = prev; - else - value = Math.min(current[j], current[j - 1], prev) + 1; - else - value = i + j; - - prev = current[j]; - current[j] = value; - } - - return current.pop(); - }, - - toBoolean: function(str, trueValues, falseValues) { - if (typeof str === "number") str = "" + str; - if (typeof str !== "string") return !!str; - str = _s.trim(str); - if (boolMatch(str, trueValues || ["true", "1"])) return true; - if (boolMatch(str, falseValues || ["false", "0"])) return false; - } - }; - - // Aliases - - _s.strip = _s.trim; - _s.lstrip = _s.ltrim; - _s.rstrip = _s.rtrim; - _s.center = _s.lrpad; - _s.rjust = _s.lpad; - _s.ljust = _s.rpad; - _s.contains = _s.include; - _s.q = _s.quote; - _s.toBool = _s.toBoolean; - - // Exporting - - // CommonJS module is defined - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) - module.exports = _s; - - exports._s = _s; - } - - // Register as a named module with AMD. - if (typeof define === 'function' && define.amd) - define('underscore.string', [], function(){ return _s; }); - - - // Integrate with Underscore.js if defined - // or create our own underscore object. - root._ = root._ || {}; - root._.string = root._.str = _s; -}(this, String); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/libpeerconnection.log b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/libpeerconnection.log deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json deleted file mode 100644 index 24f4aac7..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "name": "underscore.string", - "version": "2.3.3", - "description": "String manipulation extensions for Underscore.js javascript library.", - "homepage": "http://epeli.github.com/underscore.string/", - "contributors": [ - { - "name": "Esa-Matti Suuronen", - "email": "esa-matti@suuronen.org", - "url": "http://esa-matti.suuronen.org/" - }, - { - "name": "Edward Tsech", - "email": "edtsech@gmail.com" - }, - { - "name": "Pavel Pravosud", - "email": "pavel@pravosud.com", - "url": "" - }, - { - "name": "Sasha Koss", - "email": "kossnocorp@gmail.com", - "url": "http://koss.nocorp.me/" - }, - { - "name": "Vladimir Dronnikov", - "email": "dronnikov@gmail.com" - }, - { - "name": "Pete Kruckenberg", - "email": "https://github.com/kruckenb", - "url": "" - }, - { - "name": "Paul Chavard", - "email": "paul@chavard.net", - "url": "" - }, - { - "name": "Ed Finkler", - "email": "coj@funkatron.com", - "url": "" - } - ], - "keywords": [ - "underscore", - "string" - ], - "main": "./lib/underscore.string", - "directories": { - "lib": "./lib" - }, - "engines": { - "node": "*" - }, - "repository": { - "type": "git", - "url": "https://github.com/epeli/underscore.string.git" - }, - "bugs": { - "url": "https://github.com/epeli/underscore.string/issues" - }, - "licenses": [ - { - "type": "MIT" - } - ], - "_id": "underscore.string@2.3.3", - "dist": { - "shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", - "tarball": "http://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" - }, - "_from": "underscore.string@~2.3.1", - "_npmVersion": "1.2.32", - "_npmUser": { - "name": "epeli", - "email": "esa-matti@suuronen.org" - }, - "maintainers": [ - { - "name": "edtsech", - "email": "edtsech@gmail.com" - }, - { - "name": "rwz", - "email": "rwz@duckroll.ru" - }, - { - "name": "epeli", - "email": "esa-matti@suuronen.org" - } - ], - "_shasum": "71c08bf6b428b1133f37e78fa3a21c82f7329b0d", - "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "readme": "ERROR: No README data found!", - "scripts": {} -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/run-qunit.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/run-qunit.js deleted file mode 100644 index 44a21670..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/run-qunit.js +++ /dev/null @@ -1,45 +0,0 @@ -function waitFor(test, complete, timeout) { - var result, start = new Date().getTime() - setInterval(function interval() { - if ((new Date().getTime() - start < timeout) && !result) { - result = test() - } else { - if (!result) { - phantom.exit(1) - } else { - complete() - clearInterval(interval) - } - } - }, 100) -} - - -var fs = require('fs'), page = require('webpage').create(); -var url = 'file://localhost' + fs.workingDirectory + '/' + phantom.args[0]; - -page.onConsoleMessage = function(msg) { - console.log(msg) -} - -page.open(url, function(status) { - waitFor(function() { - return page.evaluate(function(){ - var el = document.getElementById('qunit-testresult') - return el && el.innerText.match('completed') - }) - }, function() { - var failures = page.evaluate(function() { - var el = document.getElementById('qunit-testresult'), - fails = document.getElementsByClassName('fail') - - for (var i = 0; i < fails.length; i++) - console.log(fails[i].innerText) - - console.log(el.innerText) - - return parseInt(el.getElementsByClassName('failed')[0].innerHTML) - }) - phantom.exit(failures > 0 ? 1 : 0) - }, 10000) -}) \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/speed.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/speed.js deleted file mode 100644 index 9ceeea76..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/speed.js +++ /dev/null @@ -1,148 +0,0 @@ -(function() { - - JSLitmus.test('levenshtein', function() { - return [ - _.levenshtein('pineapple', 'potato'), - _.levenshtein('seven', 'eight'), - _.levenshtein('the very same string', 'the very same string'), - _.levenshtein('very very very long string', 'something completely different') - ]; - }); - - - JSLitmus.test('trimNoNative', function() { - return _.trim(" foobar ", " "); - }); - - JSLitmus.test('trim', function() { - return _.trim(" foobar "); - }); - - JSLitmus.test('trim object-oriented', function() { - return _(" foobar ").trim(); - }); - - JSLitmus.test('trim jQuery', function() { - return jQuery.trim(" foobar "); - }); - - JSLitmus.test('ltrimp', function() { - return _.ltrim(" foobar ", " "); - }); - - JSLitmus.test('rtrimp', function() { - return _.rtrim(" foobar ", " "); - }); - - JSLitmus.test('startsWith', function() { - return _.startsWith("foobar", "foo"); - }); - - JSLitmus.test('endsWith', function() { - return _.endsWith("foobar", "xx"); - }); - - JSLitmus.test('chop', function(){ - return _('whitespace').chop(2); - }); - - JSLitmus.test('count', function(){ - return _('Hello worls').count('l'); - }); - - JSLitmus.test('insert', function() { - return _('Hello ').insert(6, 'world'); - }); - - JSLitmus.test('splice', function() { - return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); - }); - - JSLitmus.test('succ', function(){ - var let = 'a', alphabet = []; - - for (var i=0; i < 26; i++) { - alphabet.push(let); - let = _(let).succ(); - } - - return alphabet; - }); - - JSLitmus.test('titleize', function(){ - return _('the titleize string method').titleize(); - }); - - JSLitmus.test('truncate', function(){ - return _('Hello world').truncate(5); - }); - - JSLitmus.test('prune', function(){ - return _('Hello world').prune(5); - }); - - JSLitmus.test('isBlank', function(){ - return _('').isBlank(); - }); - - JSLitmus.test('escapeHTML', function(){ - _('
        Blah blah blah
        ').escapeHTML(); - }); - - JSLitmus.test('unescapeHTML', function(){ - _('<div>Blah blah blah</div>').unescapeHTML(); - }); - - JSLitmus.test('reverse', function(){ - _('Hello World').reverse(); - }); - - JSLitmus.test('pad default', function(){ - _('foo').pad(12); - }); - - JSLitmus.test('pad hash left', function(){ - _('foo').pad(12, '#'); - }); - - JSLitmus.test('pad hash right', function(){ - _('foo').pad(12, '#', 'right'); - }); - - JSLitmus.test('pad hash both', function(){ - _('foo').pad(12, '#', 'both'); - }); - - JSLitmus.test('pad hash both longPad', function(){ - _('foo').pad(12, 'f00f00f00', 'both'); - }); - - JSLitmus.test('toNumber', function(){ - _('10.232323').toNumber(2); - }); - - JSLitmus.test('strRight', function(){ - _('aaa_bbb_ccc').strRight('_'); - }); - - JSLitmus.test('strRightBack', function(){ - _('aaa_bbb_ccc').strRightBack('_'); - }); - - JSLitmus.test('strLeft', function(){ - _('aaa_bbb_ccc').strLeft('_'); - }); - - JSLitmus.test('strLeftBack', function(){ - _('aaa_bbb_ccc').strLeftBack('_'); - }); - - JSLitmus.test('join', function(){ - _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut'); - }); - - JSLitmus.test('slugify', function(){ - _("Un éléphant à l'orée du bois").slugify(); - }); - -})(); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/strings.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/strings.js deleted file mode 100644 index 77364f20..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/strings.js +++ /dev/null @@ -1,685 +0,0 @@ -$(document).ready(function() { - - // Include Underscore.string methods to Underscore namespace - _.mixin(_.str.exports()); - - module('String extensions'); - - test('Strings: naturalSort', function() { - var arr = ['foo2', 'foo1', 'foo10', 'foo30', 'foo100', 'foo10bar'], - sorted = ['foo1', 'foo2', 'foo10', 'foo10bar', 'foo30', 'foo100']; - deepEqual(arr.sort(_.naturalCmp), sorted); - }); - - test('Strings: trim', function() { - equal(_.trim(123), '123', 'Non string'); - equal(_(' foo').trim(), 'foo'); - equal(_('foo ').trim(), 'foo'); - equal(_(' foo ').trim(), 'foo'); - equal(_(' foo ').trim(), 'foo'); - equal(_(' foo ').trim(' '), 'foo', 'Manually set whitespace'); - equal(_('\t foo \t ').trim(/\s/), 'foo', 'Manually set RegExp /\\s+/'); - - equal(_('ffoo').trim('f'), 'oo'); - equal(_('ooff').trim('f'), 'oo'); - equal(_('ffooff').trim('f'), 'oo'); - - - equal(_('_-foobar-_').trim('_-'), 'foobar'); - - equal(_('http://foo/').trim('/'), 'http://foo'); - equal(_('c:\\').trim('\\'), 'c:'); - - equal(_(123).trim(), '123'); - equal(_(123).trim(3), '12'); - equal(_('').trim(), '', 'Trim empty string should return empty string'); - equal(_(null).trim(), '', 'Trim null should return empty string'); - equal(_(undefined).trim(), '', 'Trim undefined should return empty string'); - }); - - test('String: levenshtein', function() { - equal(_.levenshtein('Godfather', 'Godfather'), 0); - equal(_.levenshtein('Godfather', 'Godfathe'), 1); - equal(_.levenshtein('Godfather', 'odfather'), 1); - equal(_.levenshtein('Godfather', 'Gdfthr'), 3); - equal(_.levenshtein('seven', 'eight'), 5); - equal(_.levenshtein('123', 123), 0); - equal(_.levenshtein(321, '321'), 0); - equal(_.levenshtein('lol', null), 3); - equal(_.levenshtein('lol'), 3); - equal(_.levenshtein(null, 'lol'), 3); - equal(_.levenshtein(undefined, 'lol'), 3); - equal(_.levenshtein(), 0); - }); - - test('Strings: ltrim', function() { - equal(_(' foo').ltrim(), 'foo'); - equal(_(' foo').ltrim(), 'foo'); - equal(_('foo ').ltrim(), 'foo '); - equal(_(' foo ').ltrim(), 'foo '); - equal(_('').ltrim(), '', 'ltrim empty string should return empty string'); - equal(_(null).ltrim(), '', 'ltrim null should return empty string'); - equal(_(undefined).ltrim(), '', 'ltrim undefined should return empty string'); - - equal(_('ffoo').ltrim('f'), 'oo'); - equal(_('ooff').ltrim('f'), 'ooff'); - equal(_('ffooff').ltrim('f'), 'ooff'); - - equal(_('_-foobar-_').ltrim('_-'), 'foobar-_'); - - equal(_(123).ltrim(1), '23'); - }); - - test('Strings: rtrim', function() { - equal(_('http://foo/').rtrim('/'), 'http://foo', 'clean trailing slash'); - equal(_(' foo').rtrim(), ' foo'); - equal(_('foo ').rtrim(), 'foo'); - equal(_('foo ').rtrim(), 'foo'); - equal(_('foo bar ').rtrim(), 'foo bar'); - equal(_(' foo ').rtrim(), ' foo'); - - equal(_('ffoo').rtrim('f'), 'ffoo'); - equal(_('ooff').rtrim('f'), 'oo'); - equal(_('ffooff').rtrim('f'), 'ffoo'); - - equal(_('_-foobar-_').rtrim('_-'), '_-foobar'); - - equal(_(123).rtrim(3), '12'); - equal(_('').rtrim(), '', 'rtrim empty string should return empty string'); - equal(_(null).rtrim(), '', 'rtrim null should return empty string'); - }); - - test('Strings: capitalize', function() { - equal(_('fabio').capitalize(), 'Fabio', 'First letter is upper case'); - equal(_.capitalize('fabio'), 'Fabio', 'First letter is upper case'); - equal(_.capitalize('FOO'), 'FOO', 'Other letters unchanged'); - equal(_(123).capitalize(), '123', 'Non string'); - equal(_.capitalize(''), '', 'Capitalizing empty string returns empty string'); - equal(_.capitalize(null), '', 'Capitalizing null returns empty string'); - equal(_.capitalize(undefined), '', 'Capitalizing undefined returns empty string'); - }); - - test('Strings: join', function() { - equal(_.join('', 'foo', 'bar'), 'foobar', 'basic join'); - equal(_.join('', 1, 'foo', 2), '1foo2', 'join numbers and strings'); - equal(_.join(' ','foo', 'bar'), 'foo bar', 'join with spaces'); - equal(_.join('1', '2', '2'), '212', 'join number strings'); - equal(_.join(1, 2, 2), '212', 'join numbers'); - equal(_.join('','foo', null), 'foo', 'join null with string returns string'); - equal(_.join(null,'foo', 'bar'), 'foobar', 'join strings with null returns string'); - equal(_(' ').join('foo', 'bar'), 'foo bar', 'join object oriented'); - }); - - test('Strings: reverse', function() { - equal(_.str.reverse('foo'), 'oof' ); - equal(_.str.reverse('foobar'), 'raboof' ); - equal(_.str.reverse('foo bar'), 'rab oof' ); - equal(_.str.reverse('saippuakauppias'), 'saippuakauppias' ); - equal(_.str.reverse(123), '321', 'Non string'); - equal(_.str.reverse(123.45), '54.321', 'Non string'); - equal(_.str.reverse(''), '', 'reversing empty string returns empty string' ); - equal(_.str.reverse(null), '', 'reversing null returns empty string' ); - equal(_.str.reverse(undefined), '', 'reversing undefined returns empty string' ); - }); - - test('Strings: clean', function() { - equal(_(' foo bar ').clean(), 'foo bar'); - equal(_(123).clean(), '123'); - equal(_('').clean(), '', 'claning empty string returns empty string'); - equal(_(null).clean(), '', 'claning null returns empty string'); - equal(_(undefined).clean(), '', 'claning undefined returns empty string'); - }); - - test('Strings: sprintf', function() { - // Should be very tested function already. Thanks to - // http://www.diveintojavascript.com/projects/sprintf-for-javascript - equal(_.sprintf('Hello %s', 'me'), 'Hello me', 'basic'); - equal(_('Hello %s').sprintf('me'), 'Hello me', 'object'); - equal(_('hello %s').chain().sprintf('me').capitalize().value(), 'Hello me', 'Chaining works'); - equal(_.sprintf('%.1f', 1.22222), '1.2', 'round'); - equal(_.sprintf('%.1f', 1.17), '1.2', 'round 2'); - equal(_.sprintf('%(id)d - %(name)s', {id: 824, name: 'Hello World'}), '824 - Hello World', 'Named replacements work'); - equal(_.sprintf('%(args[0].id)d - %(args[1].name)s', {args: [{id: 824}, {name: 'Hello World'}]}), '824 - Hello World', 'Named replacements with arrays work'); - }); - - - test('Strings: vsprintf', function() { - equal(_.vsprintf('Hello %s', ['me']), 'Hello me', 'basic'); - equal(_('Hello %s').vsprintf(['me']), 'Hello me', 'object'); - equal(_('hello %s').chain().vsprintf(['me']).capitalize().value(), 'Hello me', 'Chaining works'); - equal(_.vsprintf('%.1f', [1.22222]), '1.2', 'round'); - equal(_.vsprintf('%.1f', [1.17]), '1.2', 'round 2'); - equal(_.vsprintf('%(id)d - %(name)s', [{id: 824, name: 'Hello World'}]), '824 - Hello World', 'Named replacement works'); - equal(_.vsprintf('%(args[0].id)d - %(args[1].name)s', [{args: [{id: 824}, {name: 'Hello World'}]}]), '824 - Hello World', 'Named replacement with arrays works'); - }); - - test('Strings: startsWith', function() { - ok(_('foobar').startsWith('foo'), 'foobar starts with foo'); - ok(!_('oobar').startsWith('foo'), 'oobar does not start with foo'); - ok(_(12345).startsWith(123), '12345 starts with 123'); - ok(!_(2345).startsWith(123), '2345 does not start with 123'); - ok(_('').startsWith(''), 'empty string starts with empty string'); - ok(_(null).startsWith(''), 'null starts with empty string'); - ok(!_(null).startsWith('foo'), 'null starts with foo'); - }); - - test('Strings: endsWith', function() { - ok(_('foobar').endsWith('bar'), 'foobar ends with bar'); - ok(_.endsWith('foobar', 'bar'), 'foobar ends with bar'); - ok(_.endsWith('00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4', 'mp4'), 'endsWith .mp4'); - ok(!_('fooba').endsWith('bar'), 'fooba does not end with bar'); - ok(_.endsWith(12345, 45), '12345 ends with 45'); - ok(!_.endsWith(12345, 6), '12345 does not end with 6'); - ok(_('').endsWith(''), 'empty string ends with empty string'); - ok(_(null).endsWith(''), 'null ends with empty string'); - ok(!_(null).endsWith('foo'), 'null ends with foo'); - }); - - test('Strings: include', function() { - ok(_.str.include('foobar', 'bar'), 'foobar includes bar'); - ok(!_.str.include('foobar', 'buzz'), 'foobar does not includes buzz'); - ok(_.str.include(12345, 34), '12345 includes 34'); - ok(!_.str.contains(12345, 6), '12345 does not includes 6'); - ok(!_.str.include('', 34), 'empty string includes 34'); - ok(!_.str.include(null, 34), 'null includes 34'); - ok(_.str.include(null, ''), 'null includes empty string'); - }); - - test('String: chop', function(){ - ok(_('whitespace').chop(2).length === 5, 'output [wh, it, es, pa, ce]'); - ok(_('whitespace').chop(3).length === 4, 'output [whi, tes, pac, e]'); - ok(_('whitespace').chop()[0].length === 10, 'output [whitespace]'); - ok(_(12345).chop(1).length === 5, 'output [1, 2, 3, 4, 5]'); - }); - - test('String: clean', function(){ - equal(_.clean(' foo bar '), 'foo bar'); - equal(_.clean(''), ''); - equal(_.clean(null), ''); - equal(_.clean(1), '1'); - }); - - test('String: count', function(){ - equal(_('Hello world').count('l'), 3); - equal(_('Hello world').count('Hello'), 1); - equal(_('Hello world').count('foo'), 0); - equal(_('x.xx....x.x').count('x'), 5); - equal(_('').count('x'), 0); - equal(_(null).count('x'), 0); - equal(_(undefined).count('x'), 0); - equal(_(12345).count(1), 1); - equal(_(11345).count(1), 2); - }); - - test('String: insert', function(){ - equal(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); - equal(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy'); - equal(_('').insert(100, 'Jessy'), 'Jessy'); - equal(_(null).insert(100, 'Jessy'), 'Jessy'); - equal(_(undefined).insert(100, 'Jessy'), 'Jessy'); - equal(_(12345).insert(6, 'Jessy'), '12345Jessy'); - }); - - test('String: splice', function(){ - equal(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), - 'https://edtsech@bitbucket.org/epeli/underscore.strings'); - equal(_.splice(12345, 1, 2, 321), '132145', 'Non strings'); - }); - - test('String: succ', function(){ - equal(_('a').succ(), 'b'); - equal(_('A').succ(), 'B'); - equal(_('+').succ(), ','); - equal(_(1).succ(), '2'); - }); - - test('String: titleize', function(){ - equal(_('the titleize string method').titleize(), 'The Titleize String Method'); - equal(_('the titleize string method').titleize(), 'The Titleize String Method'); - equal(_('').titleize(), '', 'Titleize empty string returns empty string'); - equal(_(null).titleize(), '', 'Titleize null returns empty string'); - equal(_(undefined).titleize(), '', 'Titleize undefined returns empty string'); - equal(_('let\'s have some fun').titleize(), 'Let\'s Have Some Fun'); - equal(_('a-dash-separated-string').titleize(), 'A-Dash-Separated-String'); - equal(_('A-DASH-SEPARATED-STRING').titleize(), 'A-Dash-Separated-String'); - equal(_(123).titleize(), '123'); - }); - - test('String: camelize', function(){ - equal(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); - equal(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); - equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); - equal(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); - equal(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); - equal(_('').camelize(), '', 'Camelize empty string returns empty string'); - equal(_(null).camelize(), '', 'Camelize null returns empty string'); - equal(_(undefined).camelize(), '', 'Camelize undefined returns empty string'); - equal(_(123).camelize(), '123'); - }); - - test('String: underscored', function(){ - equal(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); - equal(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); - equal(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); - equal(_(' the underscored string method').underscored(), 'the_underscored_string_method'); - equal(_('').underscored(), ''); - equal(_(null).underscored(), ''); - equal(_(undefined).underscored(), ''); - equal(_(123).underscored(), '123'); - }); - - test('String: dasherize', function(){ - equal(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); - equal(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); - equal(_('thisIsATest').dasherize(), 'this-is-a-test'); - equal(_('this Is A Test').dasherize(), 'this-is-a-test'); - equal(_('thisIsATest123').dasherize(), 'this-is-a-test123'); - equal(_('123thisIsATest').dasherize(), '123this-is-a-test'); - equal(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); - equal(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); - equal(_('téléphone').dasherize(), 'téléphone'); - equal(_('foo$bar').dasherize(), 'foo$bar'); - equal(_('').dasherize(), ''); - equal(_(null).dasherize(), ''); - equal(_(undefined).dasherize(), ''); - equal(_(123).dasherize(), '123'); - }); - - test('String: camelize', function(){ - equal(_.camelize('-moz-transform'), 'MozTransform'); - equal(_.camelize('webkit-transform'), 'webkitTransform'); - equal(_.camelize('under_scored'), 'underScored'); - equal(_.camelize(' with spaces'), 'withSpaces'); - equal(_('').camelize(), ''); - equal(_(null).camelize(), ''); - equal(_(undefined).camelize(), ''); - equal(_("_som eWeird---name-").camelize(), 'SomEWeirdName'); - }); - - test('String: join', function(){ - equal(_.join(1, 2, 3, 4), '21314'); - equal(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz'); - equal(_.join('',2,3,null), '23'); - equal(_.join(null,2,3), '23'); - }); - - test('String: classify', function(){ - equal(_.classify(1), '1'); - equal(_('some_class_name').classify(), 'SomeClassName'); - equal(_('my wonderfull class_name').classify(), 'MyWonderfullClassName'); - equal(_('my wonderfull.class.name').classify(), 'MyWonderfullClassName'); - }); - - test('String: humanize', function(){ - equal(_('the_humanize_string_method').humanize(), 'The humanize string method'); - equal(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method'); - equal(_('the humanize string method').humanize(), 'The humanize string method'); - equal(_('the humanize_id string method_id').humanize(), 'The humanize id string method'); - equal(_('the humanize string method ').humanize(), 'The humanize string method'); - equal(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim'); - equal(_(123).humanize(), '123'); - equal(_('').humanize(), ''); - equal(_(null).humanize(), ''); - equal(_(undefined).humanize(), ''); - }); - - test('String: truncate', function(){ - equal(_('Hello world').truncate(6, 'read more'), 'Hello read more'); - equal(_('Hello world').truncate(5), 'Hello...'); - equal(_('Hello').truncate(10), 'Hello'); - equal(_('').truncate(10), ''); - equal(_(null).truncate(10), ''); - equal(_(undefined).truncate(10), ''); - equal(_(1234567890).truncate(5), '12345...'); - }); - - test('String: prune', function(){ - equal(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more'); - equal(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world'); - equal(_('Hello, world').prune(5), 'Hello...'); - equal(_('Hello, world').prune(8), 'Hello...'); - equal(_('Hello, cruel world').prune(15), 'Hello, cruel...'); - equal(_('Hello world').prune(22), 'Hello world'); - equal(_('Привет, жеÑтокий мир').prune(6, ' read more'), 'Привет read more'); - equal(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир'); - equal(_('Привет, мир').prune(6), 'Привет...'); - equal(_('Привет, мир').prune(8), 'Привет...'); - equal(_('Привет, жеÑтокий мир').prune(16), 'Привет, жеÑтокий...'); - equal(_('Привет, мир').prune(22), 'Привет, мир'); - equal(_('alksjd!!!!!!....').prune(100, ''), 'alksjd!!!!!!....'); - equal(_(123).prune(10), '123'); - equal(_(123).prune(1, 321), '321'); - equal(_('').prune(5), ''); - equal(_(null).prune(5), ''); - equal(_(undefined).prune(5), ''); - }); - - test('String: isBlank', function(){ - ok(_('').isBlank()); - ok(_(' ').isBlank()); - ok(_('\n').isBlank()); - ok(!_('a').isBlank()); - ok(!_('0').isBlank()); - ok(!_(0).isBlank()); - ok(_('').isBlank()); - ok(_(null).isBlank()); - ok(_(undefined).isBlank()); - }); - - test('String: escapeRegExp', function(){ - equal(_.escapeRegExp(/hello(?=\sworld)/.source), 'hello\\(\\?\\=\\\\sworld\\)', 'with lookahead'); - equal(_.escapeRegExp(/hello(?!\shell)/.source), 'hello\\(\\?\\!\\\\shell\\)', 'with negative lookahead'); - }); - - test('String: escapeHTML', function(){ - equal(_('
        Blah & "blah" & \'blah\'
        ').escapeHTML(), - '<div>Blah & "blah" & 'blah'</div>'); - equal(_('<').escapeHTML(), '&lt;'); - equal(_(5).escapeHTML(), '5'); - equal(_('').escapeHTML(), ''); - equal(_(null).escapeHTML(), ''); - equal(_(undefined).escapeHTML(), ''); - }); - - test('String: unescapeHTML', function(){ - equal(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(), - '
        Blah & "blah" & \'blah\'
        '); - equal(_('&lt;').unescapeHTML(), '<'); - equal(_(''').unescapeHTML(), '\''); - equal(_(''').unescapeHTML(), '\''); - equal(_(''').unescapeHTML(), '\''); - equal(_('J').unescapeHTML(), 'J'); - equal(_('J').unescapeHTML(), 'J'); - equal(_('J').unescapeHTML(), 'J'); - equal(_('&_#39;').unescapeHTML(), '&_#39;'); - equal(_(''_;').unescapeHTML(), ''_;'); - equal(_('&#38;').unescapeHTML(), '&'); - equal(_('&amp;').unescapeHTML(), '&'); - equal(_('').unescapeHTML(), ''); - equal(_(null).unescapeHTML(), ''); - equal(_(undefined).unescapeHTML(), ''); - equal(_(5).unescapeHTML(), '5'); - // equal(_(undefined).unescapeHTML(), ''); - }); - - test('String: words', function() { - deepEqual(_('I love you!').words(), ['I', 'love', 'you!']); - deepEqual(_(' I love you! ').words(), ['I', 'love', 'you!']); - deepEqual(_('I_love_you!').words('_'), ['I', 'love', 'you!']); - deepEqual(_('I-love-you!').words(/-/), ['I', 'love', 'you!']); - deepEqual(_(123).words(), ['123'], '123 number has one word "123".'); - deepEqual(_(0).words(), ['0'], 'Zero number has one word "0".'); - deepEqual(_('').words(), [], 'Empty strings has no words.'); - deepEqual(_(' ').words(), [], 'Blank strings has no words.'); - deepEqual(_(null).words(), [], 'null has no words.'); - deepEqual(_(undefined).words(), [], 'undefined has no words.'); - }); - - test('String: chars', function() { - equal(_('Hello').chars().length, 5); - equal(_(123).chars().length, 3); - equal(_('').chars().length, 0); - equal(_(null).chars().length, 0); - equal(_(undefined).chars().length, 0); - }); - - test('String: swapCase', function(){ - equal(_('AaBbCcDdEe').swapCase(), 'aAbBcCdDeE'); - equal(_('Hello World').swapCase(), 'hELLO wORLD'); - equal(_('').swapCase(), ''); - equal(_(null).swapCase(), ''); - equal(_(undefined).swapCase(), ''); - }); - - test('String: lines', function() { - equal(_('Hello\nWorld').lines().length, 2); - equal(_('Hello World').lines().length, 1); - equal(_(123).lines().length, 1); - equal(_('').lines().length, 1); - equal(_(null).lines().length, 0); - equal(_(undefined).lines().length, 0); - }); - - test('String: pad', function() { - equal(_('1').pad(8), ' 1'); - equal(_(1).pad(8), ' 1'); - equal(_('1').pad(8, '0'), '00000001'); - equal(_('1').pad(8, '0', 'left'), '00000001'); - equal(_('1').pad(8, '0', 'right'), '10000000'); - equal(_('1').pad(8, '0', 'both'), '00001000'); - equal(_('foo').pad(8, '0', 'both'), '000foo00'); - equal(_('foo').pad(7, '0', 'both'), '00foo00'); - equal(_('foo').pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); - equal(_('').pad(2), ' '); - equal(_(null).pad(2), ' '); - equal(_(undefined).pad(2), ' '); - }); - - test('String: lpad', function() { - equal(_('1').lpad(8), ' 1'); - equal(_(1).lpad(8), ' 1'); - equal(_('1').lpad(8, '0'), '00000001'); - equal(_('1').lpad(8, '0', 'left'), '00000001'); - equal(_('').lpad(2), ' '); - equal(_(null).lpad(2), ' '); - equal(_(undefined).lpad(2), ' '); - }); - - test('String: rpad', function() { - equal(_('1').rpad(8), '1 '); - equal(_(1).lpad(8), ' 1'); - equal(_('1').rpad(8, '0'), '10000000'); - equal(_('foo').rpad(8, '0'), 'foo00000'); - equal(_('foo').rpad(7, '0'), 'foo0000'); - equal(_('').rpad(2), ' '); - equal(_(null).rpad(2), ' '); - equal(_(undefined).rpad(2), ' '); - }); - - test('String: lrpad', function() { - equal(_('1').lrpad(8), ' 1 '); - equal(_(1).lrpad(8), ' 1 '); - equal(_('1').lrpad(8, '0'), '00001000'); - equal(_('foo').lrpad(8, '0'), '000foo00'); - equal(_('foo').lrpad(7, '0'), '00foo00'); - equal(_('foo').lrpad(7, '!@$%dofjrofj'), '!!foo!!'); - equal(_('').lrpad(2), ' '); - equal(_(null).lrpad(2), ' '); - equal(_(undefined).lrpad(2), ' '); - }); - - test('String: toNumber', function() { - deepEqual(_('not a number').toNumber(), NaN); - equal(_(0).toNumber(), 0); - equal(_('0').toNumber(), 0); - equal(_('0.0').toNumber(), 0); - equal(_('0.1').toNumber(), 0); - equal(_('0.1').toNumber(1), 0.1); - equal(_(' 0.1 ').toNumber(1), 0.1); - equal(_('0000').toNumber(), 0); - equal(_('2.345').toNumber(), 2); - equal(_('2.345').toNumber(NaN), 2); - equal(_('2.345').toNumber(2), 2.35); - equal(_('2.344').toNumber(2), 2.34); - equal(_('2').toNumber(2), 2.00); - equal(_(2).toNumber(2), 2.00); - equal(_(-2).toNumber(), -2); - equal(_('-2').toNumber(), -2); - equal(_('').toNumber(), 0); - equal(_(null).toNumber(), 0); - equal(_(undefined).toNumber(), 0); - }); - - test('String: numberFormat', function() { - equal(_.numberFormat(9000), '9,000'); - equal(_.numberFormat(9000, 0), '9,000'); - equal(_.numberFormat(9000, 0, '', ''), '9000'); - equal(_.numberFormat(90000, 2), '90,000.00'); - equal(_.numberFormat(1000.754), '1,001'); - equal(_.numberFormat(1000.754, 2), '1,000.75'); - equal(_.numberFormat(1000.754, 0, ',', '.'), '1.001'); - equal(_.numberFormat(1000.754, 2, ',', '.'), '1.000,75'); - equal(_.numberFormat(1000000.754, 2, ',', '.'), '1.000.000,75'); - equal(_.numberFormat(1000000000), '1,000,000,000'); - equal(_.numberFormat(100000000), '100,000,000'); - equal(_.numberFormat('not number'), ''); - equal(_.numberFormat(), ''); - equal(_.numberFormat(null, '.', ','), ''); - equal(_.numberFormat(undefined, '.', ','), ''); - equal(_.numberFormat(new Number(5000)), '5,000'); - }); - - test('String: strRight', function() { - equal(_('This_is_a_test_string').strRight('_'), 'is_a_test_string'); - equal(_('This_is_a_test_string').strRight('string'), ''); - equal(_('This_is_a_test_string').strRight(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRight('-'), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRight(''), 'This_is_a_test_string'); - equal(_('').strRight('foo'), ''); - equal(_(null).strRight('foo'), ''); - equal(_(undefined).strRight('foo'), ''); - equal(_(12345).strRight(2), '345'); - }); - - test('String: strRightBack', function() { - equal(_('This_is_a_test_string').strRightBack('_'), 'string'); - equal(_('This_is_a_test_string').strRightBack('string'), ''); - equal(_('This_is_a_test_string').strRightBack(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRightBack(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strRightBack('-'), 'This_is_a_test_string'); - equal(_('').strRightBack('foo'), ''); - equal(_(null).strRightBack('foo'), ''); - equal(_(undefined).strRightBack('foo'), ''); - equal(_(12345).strRightBack(2), '345'); - }); - - test('String: strLeft', function() { - equal(_('This_is_a_test_string').strLeft('_'), 'This'); - equal(_('This_is_a_test_string').strLeft('This'), ''); - equal(_('This_is_a_test_string').strLeft(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeft(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeft('-'), 'This_is_a_test_string'); - equal(_('').strLeft('foo'), ''); - equal(_(null).strLeft('foo'), ''); - equal(_(undefined).strLeft('foo'), ''); - equal(_(123454321).strLeft(3), '12'); - }); - - test('String: strLeftBack', function() { - equal(_('This_is_a_test_string').strLeftBack('_'), 'This_is_a_test'); - equal(_('This_is_a_test_string').strLeftBack('This'), ''); - equal(_('This_is_a_test_string').strLeftBack(), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeftBack(''), 'This_is_a_test_string'); - equal(_('This_is_a_test_string').strLeftBack('-'), 'This_is_a_test_string'); - equal(_('').strLeftBack('foo'), ''); - equal(_(null).strLeftBack('foo'), ''); - equal(_(undefined).strLeftBack('foo'), ''); - equal(_(123454321).strLeftBack(3), '123454'); - }); - - test('Strings: stripTags', function() { - equal(_('a link').stripTags(), 'a link'); - equal(_('a link - - - - - - - - -

        Underscore.string Test Suite

        -

        -

        -
          -
          -

          Underscore.string Speed Suite

          - -
          - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_standalone.html b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_standalone.html deleted file mode 100644 index 9854c171..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_standalone.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - Underscore.strings Test Suite - - - - - - - - -

          Underscore.string Test Suite

          -

          -

          -
            - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/arrays.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/arrays.js deleted file mode 100644 index 32252a3f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/arrays.js +++ /dev/null @@ -1,200 +0,0 @@ -$(document).ready(function() { - - module("Arrays"); - - test("first", function() { - equal(_.first([1,2,3]), 1, 'can pull out the first element of an array'); - equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); - equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); - equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); - equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); - var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); - equal(result, 4, 'works on an arguments object.'); - result = _.map([[1,2,3],[1,2,3]], _.first); - equal(result.join(','), '1,1', 'works well with _.map'); - result = (function() { return _.take([1,2,3], 2); })(); - equal(result.join(','), '1,2', 'aliased as take'); - - equal(_.first(null), undefined, 'handles nulls'); - }); - - test("rest", function() { - var numbers = [1, 2, 3, 4]; - equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); - equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); - equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); - var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); - equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.rest); - equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); - result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4); - equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object'); - }); - - test("initial", function() { - equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); - equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); - var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); - equal(result.join(", "), "1, 2, 3", 'initial works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.initial); - equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); - }); - - test("last", function() { - equal(_.last([1,2,3]), 3, 'can pull out the last element of an array'); - equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); - equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); - equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); - var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); - equal(result, 4, 'works on an arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.last); - equal(result.join(','), '3,3', 'works well with _.map'); - - equal(_.last(null), undefined, 'handles nulls'); - }); - - test("compact", function() { - equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); - var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); - equal(result, 3, 'works on an arguments object'); - }); - - test("flatten", function() { - if (window.JSON) { - var list = [1, [2], [3, [[[4]]]]]; - equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); - equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); - var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); - equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); - } - }); - - test("without", function() { - var list = [1, 2, 1, 0, 3, 1, 4]; - equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); - var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); - equal(result.join(', '), '2, 3, 4', 'works on an arguments object'); - - var list = [{one : 1}, {two : 2}]; - ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); - ok(_.without(list, list[0]).length == 1, 'ditto.'); - }); - - test("uniq", function() { - var list = [1, 2, 1, 3, 1, 4]; - equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); - - var list = [1, 1, 1, 2, 2, 3]; - equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); - - var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; - var iterator = function(value) { return value.name; }; - equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); - - var iterator = function(value) { return value +1; }; - var list = [1, 2, 2, 3, 4, 4]; - equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); - - var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); - equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); - }); - - test("intersection", function() { - var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; - equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); - equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); - var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); - equal(result.join(''), 'moe', 'works on an arguments object'); - }); - - test("union", function() { - var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); - equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); - - var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); - equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); - }); - - test("difference", function() { - var result = _.difference([1, 2, 3], [2, 30, 40]); - equal(result.join(' '), '1 3', 'takes the difference of two arrays'); - - var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); - equal(result.join(' '), '3 4', 'takes the difference of three arrays'); - }); - - test('zip', function() { - var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; - var stooges = _.zip(names, ages, leaders); - equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); - }); - - test('object', function() { - var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); - var shouldBe = {moe: 30, larry: 40, curly: 50}; - ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object'); - - result = _.object([['one', 1], ['two', 2], ['three', 3]]); - shouldBe = {one: 1, two: 2, three: 3}; - ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object'); - - var stooges = {moe: 30, larry: 40, curly: 50}; - ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object'); - - ok(_.isEqual(_.object(null), {}), 'handles nulls'); - }); - - test("indexOf", function() { - var numbers = [1, 2, 3]; - numbers.indexOf = null; - equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); - var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); - equal(result, 1, 'works on an arguments object'); - equal(_.indexOf(null, 2), -1, 'handles nulls properly'); - - var numbers = [10, 20, 30, 40, 50], num = 35; - var index = _.indexOf(numbers, num, true); - equal(index, -1, '35 is not in the list'); - - numbers = [10, 20, 30, 40, 50]; num = 40; - index = _.indexOf(numbers, num, true); - equal(index, 3, '40 is in the list'); - - numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; - index = _.indexOf(numbers, num, true); - equal(index, 1, '40 is in the list'); - - numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; - index = _.indexOf(numbers, 2, 5); - equal(index, 7, 'supports the fromIndex argument'); - }); - - test("lastIndexOf", function() { - var numbers = [1, 0, 1]; - equal(_.lastIndexOf(numbers, 1), 2); - - numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; - numbers.lastIndexOf = null; - equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); - equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); - var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); - equal(result, 5, 'works on an arguments object'); - equal(_.indexOf(null, 2), -1, 'handles nulls properly'); - - numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; - index = _.lastIndexOf(numbers, 2, 2); - equal(index, 1, 'supports the fromIndex argument'); - }); - - test("range", function() { - equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); - equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); - equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); - equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); - equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); - equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); - equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); - equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/chaining.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/chaining.js deleted file mode 100644 index 16cf7bf5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/chaining.js +++ /dev/null @@ -1,59 +0,0 @@ -$(document).ready(function() { - - module("Chaining"); - - test("map/flatten/reduce", function() { - var lyrics = [ - "I'm a lumberjack and I'm okay", - "I sleep all night and I work all day", - "He's a lumberjack and he's okay", - "He sleeps all night and he works all day" - ]; - var counts = _(lyrics).chain() - .map(function(line) { return line.split(''); }) - .flatten() - .reduce(function(hash, l) { - hash[l] = hash[l] || 0; - hash[l]++; - return hash; - }, {}).value(); - ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); - }); - - test("select/reject/sortBy", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; - numbers = _(numbers).chain().select(function(n) { - return n % 2 == 0; - }).reject(function(n) { - return n % 4 == 0; - }).sortBy(function(n) { - return -n; - }).value(); - equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); - }); - - test("select/reject/sortBy in functional style", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; - numbers = _.chain(numbers).select(function(n) { - return n % 2 == 0; - }).reject(function(n) { - return n % 4 == 0; - }).sortBy(function(n) { - return -n; - }).value(); - equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); - }); - - test("reverse/concat/unshift/pop/map", function() { - var numbers = [1,2,3,4,5]; - numbers = _(numbers).chain() - .reverse() - .concat([5, 5, 5]) - .unshift(17) - .pop() - .map(function(n){ return n * 2; }) - .value(); - equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/collections.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/collections.js deleted file mode 100644 index e089626d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/collections.js +++ /dev/null @@ -1,426 +0,0 @@ -$(document).ready(function() { - - module("Collections"); - - test("each", function() { - _.each([1, 2, 3], function(num, i) { - equal(num, i + 1, 'each iterators provide value and iteration count'); - }); - - var answers = []; - _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); - equal(answers.join(', '), '5, 10, 15', 'context object property accessed'); - - answers = []; - _.forEach([1, 2, 3], function(num){ answers.push(num); }); - equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); - - answers = []; - var obj = {one : 1, two : 2, three : 3}; - obj.constructor.prototype.four = 4; - _.each(obj, function(value, key){ answers.push(key); }); - equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); - delete obj.constructor.prototype.four; - - answer = null; - _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); - ok(answer, 'can reference the original collection from inside the iterator'); - - answers = 0; - _.each(null, function(){ ++answers; }); - equal(answers, 0, 'handles a null properly'); - }); - - test('map', function() { - var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'doubled numbers'); - - doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); - - var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); - equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); - - var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); - equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); - - if (document.querySelectorAll) { - var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); - } - - var ids = _.map($('#map-test').children(), function(n){ return n.id; }); - deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.'); - - var ids = _.map(document.images, function(n){ return n.id; }); - ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); - - var ifnull = _.map(null, function(){}); - ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); - }); - - test('reduce', function() { - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'can sum up an array'); - - var context = {multiplier : 3}; - sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); - equal(sum, 18, 'can reduce with a context object'); - - sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'aliased as "inject"'); - - sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); - equal(sum, 6, 'OO-style reduce'); - - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); - equal(sum, 6, 'default initial value'); - - var ifnull; - try { - _.reduce(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); - - ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); - }); - - test('reduceRight', function() { - var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equal(list, 'bazbarfoo', 'can perform right folds'); - - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equal(list, 'bazbarfoo', 'aliased as "foldr"'); - - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); - equal(list, 'bazbarfoo', 'default initial value'); - - var ifnull; - try { - _.reduceRight(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); - - var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; }); - equal(sum, 6, 'default initial value on object'); - - ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - - equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); - - // Assert that the correct arguments are being passed. - - var args, - memo = {}, - object = {a: 1, b: 2}, - lastKey = _.keys(object).pop(); - - var expected = lastKey == 'a' - ? [memo, 1, 'a', object] - : [memo, 2, 'b', object]; - - _.reduceRight(object, function() { - args || (args = _.toArray(arguments)); - }, memo); - - deepEqual(args, expected); - - // And again, with numeric keys. - - object = {'2': 'a', '1': 'b'}; - lastKey = _.keys(object).pop(); - args = null; - - expected = lastKey == '2' - ? [memo, 'a', '2', object] - : [memo, 'b', '1', object]; - - _.reduceRight(object, function() { - args || (args = _.toArray(arguments)); - }, memo); - - deepEqual(args, expected); - }); - - test('find', function() { - var array = [1, 2, 3, 4]; - strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); - strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); - }); - - test('detect', function() { - var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); - equal(result, 2, 'found the first "2" and broke the loop'); - }); - - test('select', function() { - var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(evens.join(', '), '2, 4, 6', 'selected each even number'); - - evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); - }); - - test('reject', function() { - var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); - - var context = "obj"; - - var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){ - equal(context, "obj"); - return num % 2 != 0; - }, context); - equal(evens.join(', '), '2, 4, 6', 'rejected each odd number'); - }); - - test('all', function() { - ok(_.all([], _.identity), 'the empty set'); - ok(_.all([true, true, true], _.identity), 'all true values'); - ok(!_.all([true, false, true], _.identity), 'one false value'); - ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); - ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); - ok(_.all([1], _.identity) === true, 'cast to boolean - true'); - ok(_.all([0], _.identity) === false, 'cast to boolean - false'); - ok(_.every([true, true, true], _.identity), 'aliased as "every"'); - ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined'); - }); - - test('any', function() { - var nativeSome = Array.prototype.some; - Array.prototype.some = null; - ok(!_.any([]), 'the empty set'); - ok(!_.any([false, false, false]), 'all false values'); - ok(_.any([false, false, true]), 'one true value'); - ok(_.any([null, 0, 'yes', false]), 'a string'); - ok(!_.any([null, 0, '', false]), 'falsy values'); - ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); - ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); - ok(_.any([1], _.identity) === true, 'cast to boolean - true'); - ok(_.any([0], _.identity) === false, 'cast to boolean - false'); - ok(_.some([false, false, true]), 'aliased as "some"'); - Array.prototype.some = nativeSome; - }); - - test('include', function() { - ok(_.include([1,2,3], 2), 'two is in the array'); - ok(!_.include([1,3,9], 2), 'two is not in the array'); - ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); - ok(_([1,2,3]).include(2), 'OO-style include'); - }); - - test('invoke', function() { - var list = [[5, 1, 7], [3, 2, 1]]; - var result = _.invoke(list, 'sort'); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); - }); - - test('invoke w/ function reference', function() { - var list = [[5, 1, 7], [3, 2, 1]]; - var result = _.invoke(list, Array.prototype.sort); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); - }); - - // Relevant when using ClojureScript - test('invoke when strings have a call method', function() { - String.prototype.call = function() { - return 42; - }; - var list = [[5, 1, 7], [3, 2, 1]]; - var s = "foo"; - equal(s.call(), 42, "call function exists"); - var result = _.invoke(list, 'sort'); - equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); - delete String.prototype.call; - equal(s.call, undefined, "call function removed"); - }); - - test('pluck', function() { - var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; - equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); - }); - - test('where', function() { - var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; - var result = _.where(list, {a: 1}); - equal(result.length, 3); - equal(result[result.length - 1].b, 4); - result = _.where(list, {b: 2}); - equal(result.length, 2); - equal(result[0].a, 1); - }); - - test('max', function() { - equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); - - var neg = _.max([1, 2, 3], function(num){ return -num; }); - equal(neg, 1, 'can perform a computation-based max'); - - equal(-Infinity, _.max({}), 'Maximum value of an empty object'); - equal(-Infinity, _.max([]), 'Maximum value of an empty array'); - - equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array"); - }); - - test('min', function() { - equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); - - var neg = _.min([1, 2, 3], function(num){ return -num; }); - equal(neg, 3, 'can perform a computation-based min'); - - equal(Infinity, _.min({}), 'Minimum value of an empty object'); - equal(Infinity, _.min([]), 'Minimum value of an empty array'); - - var now = new Date(9999999999); - var then = new Date(0); - equal(_.min([now, then]), then); - - equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array"); - }); - - test('sortBy', function() { - var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; - people = _.sortBy(people, function(person){ return person.age; }); - equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); - - var list = [undefined, 4, 1, undefined, 3, 2]; - equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values'); - - var list = ["one", "two", "three", "four", "five"]; - var sorted = _.sortBy(list, 'length'); - equal(sorted.join(' '), 'one two four five three', 'sorted by length'); - - function Pair(x, y) { - this.x = x; - this.y = y; - } - - var collection = [ - new Pair(1, 1), new Pair(1, 2), - new Pair(1, 3), new Pair(1, 4), - new Pair(1, 5), new Pair(1, 6), - new Pair(2, 1), new Pair(2, 2), - new Pair(2, 3), new Pair(2, 4), - new Pair(2, 5), new Pair(2, 6), - new Pair(undefined, 1), new Pair(undefined, 2), - new Pair(undefined, 3), new Pair(undefined, 4), - new Pair(undefined, 5), new Pair(undefined, 6) - ]; - - var actual = _.sortBy(collection, function(pair) { - return pair.x; - }); - - deepEqual(actual, collection, 'sortBy should be stable'); - }); - - test('groupBy', function() { - var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); - ok('0' in parity && '1' in parity, 'created a group for each value'); - equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); - - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; - var grouped = _.groupBy(list, 'length'); - equal(grouped['3'].join(' '), 'one two six ten'); - equal(grouped['4'].join(' '), 'four five nine'); - equal(grouped['5'].join(' '), 'three seven eight'); - - var context = {}; - _.groupBy([{}], function(){ ok(this === context); }, context); - - grouped = _.groupBy([4.2, 6.1, 6.4], function(num) { - return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; - }); - equal(grouped.constructor.length, 1); - equal(grouped.hasOwnProperty.length, 2); - - var array = [{}]; - _.groupBy(array, function(value, index, obj){ ok(obj === array); }); - }); - - test('countBy', function() { - var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); - equal(parity['true'], 2); - equal(parity['false'], 3); - - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; - var grouped = _.countBy(list, 'length'); - equal(grouped['3'], 4); - equal(grouped['4'], 3); - equal(grouped['5'], 3); - - var context = {}; - _.countBy([{}], function(){ ok(this === context); }, context); - - grouped = _.countBy([4.2, 6.1, 6.4], function(num) { - return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; - }); - equal(grouped.constructor, 1); - equal(grouped.hasOwnProperty, 2); - - var array = [{}]; - _.countBy(array, function(value, index, obj){ ok(obj === array); }); - }); - - test('sortedIndex', function() { - var numbers = [10, 20, 30, 40, 50], num = 35; - var indexForNum = _.sortedIndex(numbers, num); - equal(indexForNum, 3, '35 should be inserted at index 3'); - - var indexFor30 = _.sortedIndex(numbers, 30); - equal(indexFor30, 2, '30 should be inserted at index 2'); - - var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; - var iterator = function(obj){ return obj.x; }; - strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); - strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); - - var context = {1: 2, 2: 3, 3: 4}; - iterator = function(obj){ return this[obj]; }; - strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); - }); - - test('shuffle', function() { - var numbers = _.range(10); - var shuffled = _.shuffle(numbers).sort(); - notStrictEqual(numbers, shuffled, 'original object is unmodified'); - equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); - }); - - test('toArray', function() { - ok(!_.isArray(arguments), 'arguments object is not an array'); - ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); - var a = [1,2,3]; - ok(_.toArray(a) !== a, 'array is cloned'); - equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); - - var numbers = _.toArray({one : 1, two : 2, three : 3}); - equal(numbers.join(', '), '1, 2, 3', 'object flattened into array'); - }); - - test('size', function() { - equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); - equal(_.size([1, 2, 3]), 3, 'can compute the size of an array'); - - var func = function() { - return _.size(arguments); - }; - - equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); - - equal(_.size('hello'), 5, 'can compute the size of a string'); - - equal(_.size(null), 0, 'handles nulls'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/functions.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/functions.js deleted file mode 100644 index a5296587..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/functions.js +++ /dev/null @@ -1,259 +0,0 @@ -$(document).ready(function() { - - module("Functions"); - - test("bind", function() { - var context = {name : 'moe'}; - var func = function(arg) { return "name: " + (this.name || arg); }; - var bound = _.bind(func, context); - equal(bound(), 'name: moe', 'can bind a function to a context'); - - bound = _(func).bind(context); - equal(bound(), 'name: moe', 'can do OO-style binding'); - - bound = _.bind(func, null, 'curly'); - equal(bound(), 'name: curly', 'can bind without specifying a context'); - - func = function(salutation, name) { return salutation + ': ' + name; }; - func = _.bind(func, this, 'hello'); - equal(func('moe'), 'hello: moe', 'the function was partially applied in advance'); - - var func = _.bind(func, this, 'curly'); - equal(func(), 'hello: curly', 'the function was completely applied in advance'); - - var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; - func = _.bind(func, this, 'hello', 'moe', 'curly'); - equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); - - func = function(context, message) { equal(this, context, message); }; - _.bind(func, 0, 0, 'can bind a function to `0`')(); - _.bind(func, '', '', 'can bind a function to an empty string')(); - _.bind(func, false, false, 'can bind a function to `false`')(); - - // These tests are only meaningful when using a browser without a native bind function - // To test this with a modern browser, set underscore's nativeBind to undefined - var F = function () { return this; }; - var Boundf = _.bind(F, {hello: "moe curly"}); - equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); - equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); - }); - - test("bindAll", function() { - var curly = {name : 'curly'}, moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } - }; - curly.getName = moe.getName; - _.bindAll(moe, 'getName', 'sayHi'); - curly.sayHi = moe.sayHi; - equal(curly.getName(), 'name: curly', 'unbound function is bound to current object'); - equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); - - curly = {name : 'curly'}; - moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } - }; - _.bindAll(moe); - curly.sayHi = moe.sayHi; - equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); - }); - - test("memoize", function() { - var fib = function(n) { - return n < 2 ? n : fib(n - 1) + fib(n - 2); - }; - var fastFib = _.memoize(fib); - equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); - equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); - - var o = function(str) { - return str; - }; - var fastO = _.memoize(o); - equal(o('toString'), 'toString', 'checks hasOwnProperty'); - equal(fastO('toString'), 'toString', 'checks hasOwnProperty'); - }); - - asyncTest("delay", 2, function() { - var delayed = false; - _.delay(function(){ delayed = true; }, 100); - setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); - setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); - }); - - asyncTest("defer", 1, function() { - var deferred = false; - _.defer(function(bool){ deferred = bool; }, true); - _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); - }); - - asyncTest("throttle", 2, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); throttledIncr(); throttledIncr(); - setTimeout(throttledIncr, 70); - setTimeout(throttledIncr, 120); - setTimeout(throttledIncr, 140); - setTimeout(throttledIncr, 190); - setTimeout(throttledIncr, 220); - setTimeout(throttledIncr, 240); - _.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30); - _.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400); - }); - - asyncTest("throttle arguments", 2, function() { - var value = 0; - var update = function(val){ value = val; }; - var throttledUpdate = _.throttle(update, 100); - throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); - setTimeout(function(){ throttledUpdate(4); }, 120); - setTimeout(function(){ throttledUpdate(5); }, 140); - setTimeout(function(){ throttledUpdate(6); }, 250); - _.delay(function(){ equal(value, 1, "updated to latest value"); }, 40); - _.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400); - }); - - asyncTest("throttle once", 2, function() { - var counter = 0; - var incr = function(){ return ++counter; }; - var throttledIncr = _.throttle(incr, 100); - var result = throttledIncr(); - _.delay(function(){ - equal(result, 1, "throttled functions return their value"); - equal(counter, 1, "incr was called once"); start(); - }, 220); - }); - - asyncTest("throttle twice", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); throttledIncr(); - _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220); - }); - - asyncTest("throttle repeatedly with results", 9, function() { - var counter = 0; - var incr = function(){ return ++counter; }; - var throttledIncr = _.throttle(incr, 100); - var results = []; - var saveResult = function() { results.push(throttledIncr()); }; - saveResult(); saveResult(); saveResult(); - setTimeout(saveResult, 70); - setTimeout(saveResult, 120); - setTimeout(saveResult, 140); - setTimeout(saveResult, 190); - setTimeout(saveResult, 240); - setTimeout(saveResult, 260); - _.delay(function() { - equal(results[0], 1, "incr was called once"); - equal(results[1], 1, "incr was throttled"); - equal(results[2], 1, "incr was throttled"); - equal(results[3], 1, "incr was throttled"); - equal(results[4], 2, "incr was called twice"); - equal(results[5], 2, "incr was throttled"); - equal(results[6], 2, "incr was throttled"); - equal(results[7], 3, "incr was called thrice"); - equal(results[8], 3, "incr was throttled"); - start(); - }, 400); - }); - - asyncTest("debounce", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var debouncedIncr = _.debounce(incr, 50); - debouncedIncr(); debouncedIncr(); debouncedIncr(); - setTimeout(debouncedIncr, 30); - setTimeout(debouncedIncr, 60); - setTimeout(debouncedIncr, 90); - setTimeout(debouncedIncr, 120); - setTimeout(debouncedIncr, 150); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); - }); - - asyncTest("debounce asap", 5, function() { - var a, b, c; - var counter = 0; - var incr = function(){ return ++counter; }; - var debouncedIncr = _.debounce(incr, 50, true); - a = debouncedIncr(); - b = debouncedIncr(); - c = debouncedIncr(); - equal(a, 1); - equal(b, 1); - equal(c, 1); - equal(counter, 1, 'incr was called immediately'); - setTimeout(debouncedIncr, 30); - setTimeout(debouncedIncr, 60); - setTimeout(debouncedIncr, 90); - setTimeout(debouncedIncr, 120); - setTimeout(debouncedIncr, 150); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); - }); - - asyncTest("debounce asap recursively", 2, function() { - var counter = 0; - var debouncedIncr = _.debounce(function(){ - counter++; - if (counter < 5) debouncedIncr(); - }, 50, true); - debouncedIncr(); - equal(counter, 1, 'incr was called immediately'); - _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70); - }); - - test("once", function() { - var num = 0; - var increment = _.once(function(){ num++; }); - increment(); - increment(); - equal(num, 1); - }); - - test("wrap", function() { - var greet = function(name){ return "hi: " + name; }; - var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); - equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); - - var inner = function(){ return "Hello "; }; - var obj = {name : "Moe"}; - obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); - equal(obj.hi(), "Hello Moe"); - - var noop = function(){}; - var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); - var ret = wrapped(['whats', 'your'], 'vector', 'victor'); - deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); - }); - - test("compose", function() { - var greet = function(name){ return "hi: " + name; }; - var exclaim = function(sentence){ return sentence + '!'; }; - var composed = _.compose(exclaim, greet); - equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); - - composed = _.compose(greet, exclaim); - equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); - }); - - test("after", function() { - var testAfter = function(afterAmount, timesCalled) { - var afterCalled = 0; - var after = _.after(afterAmount, function() { - afterCalled++; - }); - while (timesCalled--) after(); - return afterCalled; - }; - - equal(testAfter(5, 5), 1, "after(N) should fire after being called N times"); - equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); - equal(testAfter(0, 0), 1, "after(0) should fire immediately"); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/index.html b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/index.html deleted file mode 100644 index 064fa986..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - Underscore Test Suite - - - - - - - - - - - - - - - - -
            -
            -
            -
            -
            -
            -
            -
            -

            Underscore Speed Suite

            -

            - A representative sample of the functions are benchmarked here, to provide - a sense of how fast they might run in different browsers. - Each iteration runs on an array of 1000 elements.

            - For example, the 'intersection' test measures the number of times you can - find the intersection of two thousand-element arrays in one second. -

            -
            - - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/objects.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/objects.js deleted file mode 100644 index 22949c3b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/objects.js +++ /dev/null @@ -1,548 +0,0 @@ -$(document).ready(function() { - - module("Objects"); - - test("keys", function() { - equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); - // the test above is not safe because it relies on for-in enumeration order - var a = []; a[1] = 0; - equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); - raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values'); - raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values'); - raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives'); - raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives'); - raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives'); - }); - - test("values", function() { - equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object'); - equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"'); - }); - - test("pairs", function() { - deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); - deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); - }); - - test("invert", function() { - var obj = {first: 'Moe', second: 'Larry', third: 'Curly'}; - equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object'); - ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started'); - - var obj = {length: 3}; - ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"') - }); - - test("functions", function() { - var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; - ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); - - var Animal = function(){}; - Animal.prototype.run = function(){}; - equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); - }); - - test("extend", function() { - var result; - equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); - equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); - equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); - result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); - ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); - result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); - ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); - result = _.extend({}, {a: void 0, b: null}); - equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); - }); - - test("pick", function() { - var result; - result = _.pick({a:1, b:2, c:3}, 'a', 'c'); - ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named'); - result = _.pick({a:1, b:2, c:3}, ['b', 'c']); - ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array'); - result = _.pick({a:1, b:2, c:3}, ['a'], 'b'); - ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args'); - - var Obj = function(){}; - Obj.prototype = {a: 1, b: 2, c: 3}; - ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props'); - }); - - test("omit", function() { - var result; - result = _.omit({a:1, b:2, c:3}, 'b'); - ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property'); - result = _.omit({a:1, b:2, c:3}, 'a', 'c'); - ok(_.isEqual(result, {b:2}), 'can omit several named properties'); - result = _.omit({a:1, b:2, c:3}, ['b', 'c']); - ok(_.isEqual(result, {a:1}), 'can omit properties named in an array'); - - var Obj = function(){}; - Obj.prototype = {a: 1, b: 2, c: 3}; - ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props'); - }); - - test("defaults", function() { - var result; - var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; - - _.defaults(options, {zero: 1, one: 10, twenty: 20}); - equal(options.zero, 0, 'value exists'); - equal(options.one, 1, 'value exists'); - equal(options.twenty, 20, 'default applied'); - - _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); - equal(options.empty, "", 'value exists'); - ok(_.isNaN(options.nan), "NaN isn't overridden"); - equal(options.word, "word", 'new value is added, first one wins'); - }); - - test("clone", function() { - var moe = {name : 'moe', lucky : [13, 27, 34]}; - var clone = _.clone(moe); - equal(clone.name, 'moe', 'the clone as the attributes of the original'); - - clone.name = 'curly'; - ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); - - clone.lucky.push(101); - equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); - - equal(_.clone(undefined), void 0, 'non objects should not be changed by clone'); - equal(_.clone(1), 1, 'non objects should not be changed by clone'); - equal(_.clone(null), null, 'non objects should not be changed by clone'); - }); - - test("isEqual", function() { - function First() { - this.value = 1; - } - First.prototype.value = 1; - function Second() { - this.value = 1; - } - Second.prototype.value = 2; - - // Basic equality and identity comparisons. - ok(_.isEqual(null, null), "`null` is equal to `null`"); - ok(_.isEqual(), "`undefined` is equal to `undefined`"); - - ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); - ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); - ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); - ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); - - // String object and primitive comparisons. - ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); - ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); - ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); - ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); - - ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); - ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); - ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); - - // Number object and primitive comparisons. - ok(_.isEqual(75, 75), "Identical number primitives are equal"); - ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); - ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); - ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); - ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); - - ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); - ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); - - // Comparisons involving `NaN`. - ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); - ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); - ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); - ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); - - // Boolean object and primitive comparisons. - ok(_.isEqual(true, true), "Identical boolean primitives are equal"); - ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); - ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); - ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); - - // Common type coercions. - ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); - ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); - ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); - ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); - ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); - ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); - ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); - ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); - ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); - - // Dates. - ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); - ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); - ok(!_.isEqual(new Date(2009, 11, 13), { - getTime: function(){ - return 12606876e5; - } - }), "Date objects and objects with a `getTime` method are not equal"); - ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); - - // Functions. - ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); - - // RegExps. - ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); - ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); - ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); - ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); - ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); - - // Empty arrays, array-like objects, and object literals. - ok(_.isEqual({}, {}), "Empty object literals are equal"); - ok(_.isEqual([], []), "Empty array literals are equal"); - ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); - ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); - ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); - - ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); - ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); - - // Arrays with primitive and object values. - ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); - ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); - - // Multi-dimensional arrays. - var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); - - // Overwrite the methods defined in ES 5.1 section 15.4.4. - a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; - b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; - - // Array elements and properties. - ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); - a.push("White Rocks"); - ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); - a.push("East Boulder"); - b.push("Gunbarrel Ranch", "Teller Farm"); - ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); - - // Sparse arrays. - ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); - ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); - - // Simple objects. - ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); - ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); - ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); - ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); - ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); - - // `A` contains nested objects and arrays. - a = { - name: new String("Moe Howard"), - age: new Number(77), - stooge: true, - hobbies: ["acting"], - film: { - name: "Sing a Song of Six Pants", - release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], - minutes: new Number(16), - seconds: 54 - } - }; - - // `B` contains equivalent nested objects and arrays. - b = { - name: new String("Moe Howard"), - age: new Number(77), - stooge: true, - hobbies: ["acting"], - film: { - name: "Sing a Song of Six Pants", - release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], - minutes: new Number(16), - seconds: 54 - } - }; - ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); - - // Instances. - ok(_.isEqual(new First, new First), "Object instances are equal"); - ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); - ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); - ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); - - // Circular Arrays. - (a = []).push(a); - (b = []).push(b); - ok(_.isEqual(a, b), "Arrays containing circular references are equal"); - a.push(new String("Larry")); - b.push(new String("Larry")); - ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); - a.push("Shemp"); - b.push("Curly"); - ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); - - // More circular arrays #767. - a = ["everything is checked but", "this", "is not"]; - a[1] = a; - b = ["everything is checked but", ["this", "array"], "is not"]; - ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal"); - - // Circular Objects. - a = {abc: null}; - b = {abc: null}; - a.abc = a; - b.abc = b; - ok(_.isEqual(a, b), "Objects containing circular references are equal"); - a.def = 75; - b.def = 75; - ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); - a.def = new Number(75); - b.def = new Number(63); - ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); - - // More circular objects #767. - a = {everything: "is checked", but: "this", is: "not"}; - a.but = a; - b = {everything: "is checked", but: {that:"object"}, is: "not"}; - ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal"); - - // Cyclic Structures. - a = [{abc: null}]; - b = [{abc: null}]; - (a[0].abc = a).push(a); - (b[0].abc = b).push(b); - ok(_.isEqual(a, b), "Cyclic structures are equal"); - a[0].def = "Larry"; - b[0].def = "Larry"; - ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); - a[0].def = new String("Larry"); - b[0].def = new String("Curly"); - ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); - - // Complex Circular References. - a = {foo: {b: {foo: {c: {foo: null}}}}}; - b = {foo: {b: {foo: {c: {foo: null}}}}}; - a.foo.b.foo.c.foo = a; - b.foo.b.foo.c.foo = b; - ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); - - // Chaining. - ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); - equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); - - // Custom `isEqual` methods. - var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; - var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; - - ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); - ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); - ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); - ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); - - // Objects from another frame. - ok(_.isEqual({}, iObject)); - }); - - test("isEmpty", function() { - ok(!_([1]).isEmpty(), '[1] is not empty'); - ok(_.isEmpty([]), '[] is empty'); - ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); - ok(_.isEmpty({}), '{} is empty'); - ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); - ok(_.isEmpty(null), 'null is empty'); - ok(_.isEmpty(), 'undefined is empty'); - ok(_.isEmpty(''), 'the empty string is empty'); - ok(!_.isEmpty('moe'), 'but other strings are not'); - - var obj = {one : 1}; - delete obj.one; - ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); - }); - - // Setup remote variables for iFrame tests. - var iframe = document.createElement('iframe'); - jQuery(iframe).appendTo(document.body); - var iDoc = iframe.contentDocument || iframe.contentWindow.document; - iDoc.write( - "" - ); - iDoc.close(); - - test("isElement", function() { - ok(!_.isElement('div'), 'strings are not dom elements'); - ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); - ok(_.isElement(iElement), 'even from another frame'); - }); - - test("isArguments", function() { - var args = (function(){ return arguments; })(1, 2, 3); - ok(!_.isArguments('string'), 'a string is not an arguments object'); - ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); - ok(_.isArguments(args), 'but the arguments object is an arguments object'); - ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); - ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); - ok(_.isArguments(iArguments), 'even from another frame'); - }); - - test("isObject", function() { - ok(_.isObject(arguments), 'the arguments object is object'); - ok(_.isObject([1, 2, 3]), 'and arrays'); - ok(_.isObject($('html')[0]), 'and DOM element'); - ok(_.isObject(iElement), 'even from another frame'); - ok(_.isObject(function () {}), 'and functions'); - ok(_.isObject(iFunction), 'even from another frame'); - ok(!_.isObject(null), 'but not null'); - ok(!_.isObject(undefined), 'and not undefined'); - ok(!_.isObject('string'), 'and not string'); - ok(!_.isObject(12), 'and not number'); - ok(!_.isObject(true), 'and not boolean'); - ok(_.isObject(new String('string')), 'but new String()'); - }); - - test("isArray", function() { - ok(!_.isArray(arguments), 'the arguments object is not an array'); - ok(_.isArray([1, 2, 3]), 'but arrays are'); - ok(_.isArray(iArray), 'even from another frame'); - }); - - test("isString", function() { - ok(!_.isString(document.body), 'the document body is not a string'); - ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); - ok(_.isString(iString), 'even from another frame'); - }); - - test("isNumber", function() { - ok(!_.isNumber('string'), 'a string is not a number'); - ok(!_.isNumber(arguments), 'the arguments object is not a number'); - ok(!_.isNumber(undefined), 'undefined is not a number'); - ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); - ok(_.isNumber(NaN), 'NaN *is* a number'); - ok(_.isNumber(Infinity), 'Infinity is a number'); - ok(_.isNumber(iNumber), 'even from another frame'); - ok(!_.isNumber('1'), 'numeric strings are not numbers'); - }); - - test("isBoolean", function() { - ok(!_.isBoolean(2), 'a number is not a boolean'); - ok(!_.isBoolean("string"), 'a string is not a boolean'); - ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); - ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); - ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); - ok(!_.isBoolean(undefined), 'undefined is not a boolean'); - ok(!_.isBoolean(NaN), 'NaN is not a boolean'); - ok(!_.isBoolean(null), 'null is not a boolean'); - ok(_.isBoolean(true), 'but true is'); - ok(_.isBoolean(false), 'and so is false'); - ok(_.isBoolean(iBoolean), 'even from another frame'); - }); - - test("isFunction", function() { - ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); - ok(!_.isFunction('moe'), 'strings are not functions'); - ok(_.isFunction(_.isFunction), 'but functions are'); - ok(_.isFunction(iFunction), 'even from another frame'); - }); - - test("isDate", function() { - ok(!_.isDate(100), 'numbers are not dates'); - ok(!_.isDate({}), 'objects are not dates'); - ok(_.isDate(new Date()), 'but dates are'); - ok(_.isDate(iDate), 'even from another frame'); - }); - - test("isRegExp", function() { - ok(!_.isRegExp(_.identity), 'functions are not RegExps'); - ok(_.isRegExp(/identity/), 'but RegExps are'); - ok(_.isRegExp(iRegExp), 'even from another frame'); - }); - - test("isFinite", function() { - ok(!_.isFinite(undefined), 'undefined is not Finite'); - ok(!_.isFinite(null), 'null is not Finite'); - ok(!_.isFinite(NaN), 'NaN is not Finite'); - ok(!_.isFinite(Infinity), 'Infinity is not Finite'); - ok(!_.isFinite(-Infinity), '-Infinity is not Finite'); - ok(!_.isFinite('12'), 'Strings are not numbers'); - var obj = new Number(5); - ok(_.isFinite(obj), 'Number instances can be finite'); - ok(_.isFinite(0), '0 is Finite'); - ok(_.isFinite(123), 'Ints are Finite'); - ok(_.isFinite(-12.44), 'Floats are Finite'); - }); - - test("isNaN", function() { - ok(!_.isNaN(undefined), 'undefined is not NaN'); - ok(!_.isNaN(null), 'null is not NaN'); - ok(!_.isNaN(0), '0 is not NaN'); - ok(_.isNaN(NaN), 'but NaN is'); - ok(_.isNaN(iNaN), 'even from another frame'); - ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); - }); - - test("isNull", function() { - ok(!_.isNull(undefined), 'undefined is not null'); - ok(!_.isNull(NaN), 'NaN is not null'); - ok(_.isNull(null), 'but null is'); - ok(_.isNull(iNull), 'even from another frame'); - }); - - test("isUndefined", function() { - ok(!_.isUndefined(1), 'numbers are defined'); - ok(!_.isUndefined(null), 'null is defined'); - ok(!_.isUndefined(false), 'false is defined'); - ok(!_.isUndefined(NaN), 'NaN is defined'); - ok(_.isUndefined(), 'nothing is undefined'); - ok(_.isUndefined(undefined), 'undefined is undefined'); - ok(_.isUndefined(iUndefined), 'even from another frame'); - }); - - if (window.ActiveXObject) { - test("IE host objects", function() { - var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); - ok(!_.isNumber(xml)); - ok(!_.isBoolean(xml)); - ok(!_.isNaN(xml)); - ok(!_.isFunction(xml)); - ok(!_.isNull(xml)); - ok(!_.isUndefined(xml)); - }); - } - - test("tap", function() { - var intercepted = null; - var interceptor = function(obj) { intercepted = obj; }; - var returned = _.tap(1, interceptor); - equal(intercepted, 1, "passes tapped object to interceptor"); - equal(returned, 1, "returns tapped object"); - - returned = _([1,2,3]).chain(). - map(function(n){ return n * 2; }). - max(). - tap(interceptor). - value(); - ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); - }); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/speed.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/speed.js deleted file mode 100644 index 05e3f2a3..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/speed.js +++ /dev/null @@ -1,75 +0,0 @@ -(function() { - - var numbers = []; - for (var i=0; i<1000; i++) numbers.push(i); - var objects = _.map(numbers, function(n){ return {num : n}; }); - var randomized = _.sortBy(numbers, function(){ return Math.random(); }); - var deep = _.map(_.range(100), function() { return _.range(1000); }); - - JSLitmus.test('_.each()', function() { - var timesTwo = []; - _.each(numbers, function(num){ timesTwo.push(num * 2); }); - return timesTwo; - }); - - JSLitmus.test('_(list).each()', function() { - var timesTwo = []; - _(numbers).each(function(num){ timesTwo.push(num * 2); }); - return timesTwo; - }); - - JSLitmus.test('jQuery.each()', function() { - var timesTwo = []; - jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); - return timesTwo; - }); - - JSLitmus.test('_.map()', function() { - return _.map(objects, function(obj){ return obj.num; }); - }); - - JSLitmus.test('jQuery.map()', function() { - return jQuery.map(objects, function(obj){ return obj.num; }); - }); - - JSLitmus.test('_.pluck()', function() { - return _.pluck(objects, 'num'); - }); - - JSLitmus.test('_.uniq()', function() { - return _.uniq(randomized); - }); - - JSLitmus.test('_.uniq() (sorted)', function() { - return _.uniq(numbers, true); - }); - - JSLitmus.test('_.sortBy()', function() { - return _.sortBy(numbers, function(num){ return -num; }); - }); - - JSLitmus.test('_.isEqual()', function() { - return _.isEqual(numbers, randomized); - }); - - JSLitmus.test('_.keys()', function() { - return _.keys(objects); - }); - - JSLitmus.test('_.values()', function() { - return _.values(objects); - }); - - JSLitmus.test('_.intersection()', function() { - return _.intersection(numbers, randomized); - }); - - JSLitmus.test('_.range()', function() { - return _.range(1000); - }); - - JSLitmus.test('_.flatten()', function() { - return _.flatten(deep); - }); - -})(); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/utility.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/utility.js deleted file mode 100644 index c9be20ad..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/test/test_underscore/utility.js +++ /dev/null @@ -1,249 +0,0 @@ -$(document).ready(function() { - - var templateSettings; - - module("Utility", { - - setup: function() { - templateSettings = _.clone(_.templateSettings); - }, - - teardown: function() { - _.templateSettings = templateSettings; - } - - }); - - test("#750 - Return _ instance.", 2, function() { - var instance = _([]); - ok(_(instance) === instance); - ok(new _(instance) === instance); - }); - - test("identity", function() { - var moe = {name : 'moe'}; - equal(_.identity(moe), moe, 'moe is the same as his identity'); - }); - - test("uniqueId", function() { - var ids = [], i = 0; - while(i++ < 100) ids.push(_.uniqueId()); - equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); - }); - - test("times", function() { - var vals = []; - _.times(3, function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); - // - vals = []; - _(3).times(function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); - }); - - test("mixin", function() { - _.mixin({ - myReverse: function(string) { - return string.split('').reverse().join(''); - } - }); - equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); - equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); - }); - - test("_.escape", function() { - equal(_.escape("Curly & Moe"), "Curly & Moe"); - equal(_.escape("Curly & Moe"), "Curly &amp; Moe"); - equal(_.escape(null), ''); - }); - - test("_.unescape", function() { - var string = "Curly & Moe"; - equal(_.unescape("Curly & Moe"), string); - equal(_.unescape("Curly &amp; Moe"), "Curly & Moe"); - equal(_.unescape(null), ''); - equal(_.unescape(_.escape(string)), string); - }); - - test("template", function() { - var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); - var result = basicTemplate({thing : 'This'}); - equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); - - var sansSemicolonTemplate = _.template("A <% this %> B"); - equal(sansSemicolonTemplate(), "A B"); - - var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); - equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); - - var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); - equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); - - var fancyTemplate = _.template("
              <% \ - for (key in people) { \ - %>
            • <%= people[key] %>
            • <% } %>
            "); - result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); - equal(result, "
            • Moe
            • Larry
            • Curly
            ", 'can run arbitrary javascript in templates'); - - var escapedCharsInJavascriptTemplate = _.template("
              <% _.each(numbers.split('\\n'), function(item) { %>
            • <%= item %>
            • <% }) %>
            "); - result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); - equal(result, "
            • one
            • two
            • three
            • four
            ", 'Can use escaped characters (e.g. \\n) in Javascript'); - - var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
            \">
            <% }); %>"); - result = namespaceCollisionTemplate({ - pageCount: 3, - thumbnails: { - 1: "p1-thumbnail.gif", - 2: "p2-thumbnail.gif", - 3: "p3-thumbnail.gif" - } - }); - equal(result, "3 p3-thumbnail.gif
            "); - - var noInterpolateTemplate = _.template("

            Just some text. Hey, I know this is silly but it aids consistency.

            "); - result = noInterpolateTemplate(); - equal(result, "

            Just some text. Hey, I know this is silly but it aids consistency.

            "); - - var quoteTemplate = _.template("It's its, not it's"); - equal(quoteTemplate({}), "It's its, not it's"); - - var quoteInStatementAndBody = _.template("<%\ - if(foo == 'bar'){ \ - %>Statement quotes and 'quotes'.<% } %>"); - equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); - - var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); - equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); - - var template = _.template("<%- value %>"); - var result = template({value: " - - - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/index.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/index.js deleted file mode 100644 index 2cf0ca5b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./underscore'); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/package.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/package.json deleted file mode 100644 index c58f39c2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "underscore", - "description": "JavaScript's functional programming helper library.", - "homepage": "http://underscorejs.org", - "keywords": [ - "util", - "functional", - "server", - "client", - "browser" - ], - "author": { - "name": "Jeremy Ashkenas", - "email": "jeremy@documentcloud.org" - }, - "repository": { - "type": "git", - "url": "git://github.com/documentcloud/underscore.git" - }, - "main": "underscore.js", - "version": "1.4.4", - "devDependencies": { - "phantomjs": "0.2.2" - }, - "scripts": { - "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true" - }, - "_id": "underscore@1.4.4", - "dist": { - "shasum": "61a6a32010622afa07963bf325203cf12239d604", - "tarball": "http://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz" - }, - "_npmVersion": "1.1.63", - "_npmUser": { - "name": "jashkenas", - "email": "jashkenas@gmail.com" - }, - "maintainers": [ - { - "name": "jashkenas", - "email": "jashkenas@gmail.com" - } - ], - "directories": {}, - "_shasum": "61a6a32010622afa07963bf325203cf12239d604", - "_from": "underscore@~1.4.3", - "_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", - "bugs": { - "url": "https://github.com/documentcloud/underscore/issues" - }, - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore-min.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore-min.js deleted file mode 100644 index c1d9d3ae..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore-min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).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.indexi;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=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 w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){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;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore.js deleted file mode 100644 index a12f0d96..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore.js +++ /dev/null @@ -1,1226 +0,0 @@ -// Underscore.js 1.4.4 -// http://underscorejs.org -// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `global` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; - - // 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, - concat = ArrayProto.concat, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // 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 via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.4.4'; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects with the built-in `forEach`, arrays, and raw objects. - // Delegates to **ECMAScript 5**'s native `forEach` if available. - var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return; - if (nativeForEach && obj.forEach === nativeForEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - for (var key in obj) { - if (_.has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === breaker) return; - } - } - } - }; - - // Return the results of applying the iterator to each element. - // Delegates to **ECMAScript 5**'s native `map` if available. - _.map = _.collect = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); - each(obj, function(value, index, list) { - results[results.length] = iterator.call(context, value, index, list); - }); - return results; - }; - - var reduceError = 'Reduce of empty array with no initial value'; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. - _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduce && obj.reduce === nativeReduce) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - // Delegates to **ECMAScript 5**'s native `reduceRight` if available. - _.reduceRight = _.foldr = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); - } - var length = obj.length; - if (length !== +length) { - var keys = _.keys(obj); - length = keys.length; - } - each(obj, function(value, index, list) { - index = keys ? keys[--length] : --length; - if (!initial) { - memo = obj[index]; - initial = true; - } else { - memo = iterator.call(context, memo, obj[index], index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { - var result; - any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // Aliased as `select`. - _.filter = _.select = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); - each(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { - return _.filter(obj, function(value, index, list) { - return !iterator.call(context, value, index, list); - }, context); - }; - - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = true; - if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); - each(obj, function(value, index, list) { - if (!(result = result && iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = false; - if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); - each(obj, function(value, index, list) { - if (result || (result = iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; - return any(obj, function(value) { - return value === target; - }); - }; - - // 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) { - return (isFunc ? method : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs, first) { - if (_.isEmpty(attrs)) return first ? null : []; - return _[first ? 'find' : 'filter'](obj, function(value) { - for (var key in attrs) { - if (attrs[key] !== value[key]) return false; - } - return true; - }); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.where(obj, attrs, true); - }; - - // Return the maximum element or (element-based computation). - // Can't optimize arrays of integers longer than 65,535 elements. - // See: https://bugs.webkit.org/show_bug.cgi?id=80797 - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.max.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity, value: -Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed >= result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.min.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity, value: Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Shuffle an array. - _.shuffle = function(obj) { - var rand; - var index = 0; - var shuffled = []; - each(obj, function(value) { - rand = _.random(index++); - shuffled[index - 1] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; - - // An internal function to generate lookup iterators. - var lookupIterator = function(value) { - return _.isFunction(value) ? value : function(obj){ return obj[value]; }; - }; - - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, value, context) { - var iterator = lookupIterator(value); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value : value, - index : index, - criteria : iterator.call(context, 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 ? -1 : 1; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(obj, value, context, behavior) { - var result = {}; - var iterator = lookupIterator(value || _.identity); - each(obj, function(value, index) { - var key = iterator.call(context, value, index, obj); - behavior(result, key, value); - }); - 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 = function(obj, value, context) { - return group(obj, value, context, function(result, key, value) { - (_.has(result, key) ? result[key] : (result[key] = [])).push(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 = function(obj, value, context) { - return group(obj, value, context, function(result, key) { - if (!_.has(result, key)) result[key] = 0; - result[key]++; - }); - }; - - // 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, iterator, context) { - iterator = iterator == null ? _.identity : lookupIterator(iterator); - var value = iterator.call(context, obj); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >>> 1; - iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; - } - return low; - }; - - // Safely convert anything iterable into a real, live array. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; - }; - - // 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; - return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; - }; - - // 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. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 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. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if ((n != null) && !guard) { - return slice.call(array, Math.max(array.length - n, 0)); - } else { - return array[array.length - 1]; - } - }; - - // 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. The **guard** - // check allows it to work with `_.map`. - _.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, output) { - each(input, function(value) { - if (_.isArray(value)) { - shallow ? push.apply(output, value) : flatten(value, shallow, output); - } else { - output.push(value); - } - }); - return output; - }; - - // Return a completely flattened version of an array. - _.flatten = function(array, shallow) { - return flatten(array, shallow, []); - }; - - // 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, iterator, context) { - if (_.isFunction(isSorted)) { - context = iterator; - iterator = isSorted; - isSorted = false; - } - var initial = iterator ? _.map(array, iterator, context) : array; - var results = []; - var seen = []; - each(initial, function(value, index) { - if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { - seen.push(value); - results.push(array[index]); - } - }); - return results; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(concat.apply(ArrayProto, arguments)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; - }); - }); - }; - - // 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 = concat.apply(ArrayProto, slice.call(arguments, 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() { - var args = slice.call(arguments); - var length = _.max(_.pluck(args, 'length')); - var results = new Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(args, "" + i); - } - return results; - }; - - // 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) { - if (list == null) return {}; - var result = {}; - for (var i = 0, l = list.length; i < l; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, l = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); - for (; i < l; i++) if (array[i] === item) return i; - return -1; - }; - - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var hasIndex = from != null; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { - return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); - } - var i = (hasIndex ? from : array.length); - while (i--) if (array[i] === item) return i; - return -1; - }; - - // 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 (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; - - var len = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(len); - - while(idx < len) { - range[idx++] = start; - start += step; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // 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 (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - var args = slice.call(arguments, 2); - return function() { - return func.apply(context, args.concat(slice.call(arguments))); - }; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. - _.partial = function(func) { - var args = slice.call(arguments, 1); - return function() { - return func.apply(this, args.concat(slice.call(arguments))); - }; - }; - - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length === 0) funcs = _.functions(obj); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; - - // 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 = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. - _.throttle = function(func, wait) { - var context, args, timeout, result; - var previous = 0; - var later = function() { - previous = new Date; - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - 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, result; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) result = func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(context, args); - return result; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - memo = func.apply(this, arguments); - func = null; - return memo; - }; - }; - - // 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 function() { - var args = [func]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - }; - - // 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 funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - if (times <= 0) return func(); - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var values = []; - for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); - return values; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var pairs = []; - for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; - 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 = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - each(keys, function(key) { - if (key in obj) copy[key] = obj[key]; - }); - return copy; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - for (var key in obj) { - if (!_.contains(keys, key)) copy[key] = obj[key]; - } - return copy; - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - if (obj[prop] == null) obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // 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; - }; - - // 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, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (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; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; - } - if (typeof a != 'object' || typeof b != 'object') 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`. - 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); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Objects with different constructors are not equivalent, but `Object`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))) { - return false; - } - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // 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 (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // 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) { - return obj === Object(obj); - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) == '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; - } - - // Optimize `isFunction` if appropriate. - if (typeof (/./) !== 'function') { - _.isFunction = function(obj) { - return typeof obj === 'function'; - }; - } - - // 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 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 iterators. - _.identity = function(value) { - return value; - }; - - // Run a function **n** times. - _.times = function(n, iterator, context) { - var accum = Array(n); - for (var i = 0; i < n; i++) accum[i] = iterator.call(context, 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)); - }; - - // List of HTML entities for escaping. - var entityMap = { - escape: { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/' - } - }; - entityMap.unescape = _.invert(entityMap.escape); - - // Regexes containing the keys and values listed immediately above. - var entityRegexes = { - escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), - unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') - }; - - // Functions for escaping and unescaping strings to/from HTML interpolation. - _.each(['escape', 'unescape'], function(method) { - _[method] = function(string) { - if (string == null) return ''; - return ('' + string).replace(entityRegexes[method], function(match) { - return entityMap[method][match]; - }); - }; - }); - - // If the value of the named property is a function then invoke it; - // otherwise, return it. - _.result = function(object, property) { - if (object == null) return null; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; - - // 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.call(this, func.apply(_, args)); - }; - }); - }; - - // 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', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - var render; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = new 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, function(match) { return '\\' + escapes[match]; }); - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } - if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } - if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - index = offset + match.length; - 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 { - render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled function source as a convenience for precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; - - // 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(obj) { - return this._chain ? _(obj).chain() : obj; - }; - - // 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.call(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.call(this, method.apply(this._wrapped, arguments)); - }; - }); - - _.extend(_.prototype, { - - // Start chaining a wrapped Underscore object. - chain: function() { - this._chain = true; - return this; - }, - - // Extracts the result from a wrapped and chained object. - value: function() { - return this._wrapped; - } - - }); - -}).call(this); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/package.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/package.json deleted file mode 100644 index 19c13e28..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/argparse/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "argparse", - "description": "Very powerful CLI arguments parser. Native port of argparse - python's options parsing library", - "version": "0.1.15", - "keywords": [ - "cli", - "parser", - "argparse", - "option", - "args" - ], - "homepage": "https://github.com/nodeca/argparse", - "contributors": [ - { - "name": "Eugene Shkuropat" - }, - { - "name": "Paul Jacobson" - } - ], - "bugs": { - "url": "https://github.com/nodeca/argparse/issues" - }, - "license": { - "type": "MIT", - "url": "https://github.com/nodeca/argparse/blob/master/LICENSE" - }, - "repository": { - "type": "git", - "url": "git://github.com/nodeca/argparse.git" - }, - "main": "./index.js", - "scripts": { - "test": "make test" - }, - "dependencies": { - "underscore": "~1.4.3", - "underscore.string": "~2.3.1" - }, - "devDependencies": { - "mocha": "*" - }, - "engines": { - "node": ">= 0.6.0" - }, - "readme": "argparse\n========\n\n[![Build Status](https://secure.travis-ci.org/nodeca/argparse.png?branch=master)](http://travis-ci.org/nodeca/argparse)\n\nCLI arguments parser for node.js. Javascript port of python's\n[argparse](http://docs.python.org/dev/library/argparse.html) module\n(original version 3.2). That's a full port, except some very rare options,\nrecorded in issue tracker.\n\n**NB.** Method names changed to camelCase. See [generated docs](http://nodeca.github.com/argparse/).\n\n\nExample\n=======\n\ntest.js file:\n\n```javascript\n#!/usr/bin/env node\n'use strict';\n\nvar ArgumentParser = require('../lib/argparse').ArgumentParser;\nvar parser = new ArgumentParser({\n version: '0.0.1',\n addHelp:true,\n description: 'Argparse example'\n});\nparser.addArgument(\n [ '-f', '--foo' ],\n {\n help: 'foo bar'\n }\n);\nparser.addArgument(\n [ '-b', '--bar' ],\n {\n help: 'bar foo'\n }\n);\nvar args = parser.parseArgs();\nconsole.dir(args);\n```\n\nDisplay help:\n\n```\n$ ./test.js -h\nusage: example.js [-h] [-v] [-f FOO] [-b BAR]\n\nArgparse example\n\nOptional arguments:\n -h, --help Show this help message and exit.\n -v, --version Show program's version number and exit.\n -f FOO, --foo FOO foo bar\n -b BAR, --bar BAR bar foo\n```\n\nParse arguments:\n\n```\n$ ./test.js -f=3 --bar=4\n{ foo: '3', bar: '4' }\n```\n\nMore [examples](https://github.com/nodeca/argparse/tree/master/examples).\n\n\nArgumentParser objects\n======================\n\n```\nnew ArgumentParser({paramters hash});\n```\n\nCreates a new ArgumentParser object.\n\n**Supported params:**\n\n- ```description``` - Text to display before the argument help.\n- ```epilog``` - Text to display after the argument help.\n- ```addHelp``` - Add a -h/–help option to the parser. (default: True)\n- ```argumentDefault``` - Set the global default value for arguments. (default: None)\n- ```parents``` - A list of ArgumentParser objects whose arguments should also be included.\n- ```prefixChars``` - The set of characters that prefix optional arguments. (default: ‘-‘)\n- ```formatterClass``` - A class for customizing the help output.\n- ```prog``` - The name of the program (default: sys.argv[0])\n- ```usage``` - The string describing the program usage (default: generated)\n- ```conflictHandler``` - Usually unnecessary, defines strategy for resolving conflicting optionals.\n\n**Not supportied yet**\n\n- ```fromfilePrefixChars``` - The set of characters that prefix files from which additional arguments should be read.\n\n\nDetails in [original ArgumentParser guide](http://docs.python.org/dev/library/argparse.html#argumentparser-objects)\n\n\naddArgument() method\n====================\n\n```\nArgumentParser.addArgument([names or flags], {options})\n```\n\nDefines how a single command-line argument should be parsed.\n\n- ```name or flags``` - Either a name or a list of option strings, e.g. foo or -f, --foo.\n\nOptions:\n\n- ```action``` - The basic type of action to be taken when this argument is encountered at the command line.\n- ```nargs```- The number of command-line arguments that should be consumed.\n- ```constant``` - A constant value required by some action and nargs selections.\n- ```defaultValue``` - The value produced if the argument is absent from the command line.\n- ```type``` - The type to which the command-line argument should be converted.\n- ```choices``` - A container of the allowable values for the argument.\n- ```required``` - Whether or not the command-line option may be omitted (optionals only).\n- ```help``` - A brief description of what the argument does.\n- ```metavar``` - A name for the argument in usage messages.\n- ```dest``` - The name of the attribute to be added to the object returned by parseArgs().\n\nDetails in [original add_argument guide](http://docs.python.org/dev/library/argparse.html#the-add-argument-method)\n\n\nAction (some details)\n================\n\nArgumentParser objects associate command-line arguments with actions.\nThese actions can do just about anything with the command-line arguments associated\nwith them, though most actions simply add an attribute to the object returned by\nparseArgs(). The action keyword argument specifies how the command-line arguments\nshould be handled. The supported actions are:\n\n- ```store``` - Just stores the argument’s value. This is the default action.\n- ```storeConst``` - Stores value, specified by the const keyword argument.\n (Note that the const keyword argument defaults to the rather unhelpful None.)\n The 'storeConst' action is most commonly used with optional arguments, that\n specify some sort of flag.\n- ```storeTrue``` and ```storeFalse``` - Stores values True and False\n respectively. These are special cases of 'storeConst'.\n- ```append``` - Stores a list, and appends each argument value to the list.\n This is useful to allow an option to be specified multiple times.\n- ```appendConst``` - Stores a list, and appends value, specified by the\n const keyword argument to the list. (Note, that the const keyword argument defaults\n is None.) The 'appendConst' action is typically used when multiple arguments need\n to store constants to the same list.\n- ```count``` - Counts the number of times a keyword argument occurs. For example,\n used for increasing verbosity levels.\n- ```help``` - Prints a complete help message for all the options in the current\n parser and then exits. By default a help action is automatically added to the parser.\n See ArgumentParser for details of how the output is created.\n- ```version``` - Prints version information and exit. Expects a `version=`\n keyword argument in the addArgument() call.\n\nDetails in [original action guide](http://docs.python.org/dev/library/argparse.html#action)\n\n\nSub-commands\n============\n\nArgumentParser.addSubparsers()\n\nMany programs split their functionality into a number of sub-commands, for\nexample, the svn program can invoke sub-commands like `svn checkout`, `svn update`,\nand `svn commit`. Splitting up functionality this way can be a particularly good\nidea when a program performs several different functions which require different\nkinds of command-line arguments. `ArgumentParser` supports creation of such\nsub-commands with `addSubparsers()` method. The `addSubparsers()` method is\nnormally called with no arguments and returns an special action object.\nThis object has a single method `addParser()`, which takes a command name and\nany `ArgumentParser` constructor arguments, and returns an `ArgumentParser` object\nthat can be modified as usual.\n\nExample:\n\nsub_commands.js\n```javascript\n#!/usr/bin/env node\n'use strict';\n\nvar ArgumentParser = require('../lib/argparse').ArgumentParser;\nvar parser = new ArgumentParser({\n version: '0.0.1',\n addHelp:true,\n description: 'Argparse examples: sub-commands',\n});\n\nvar subparsers = parser.addSubparsers({\n title:'subcommands',\n dest:\"subcommand_name\"\n});\n\nvar bar = subparsers.addParser('c1', {addHelp:true});\nbar.addArgument(\n [ '-f', '--foo' ],\n {\n action: 'store',\n help: 'foo3 bar3'\n }\n);\nvar bar = subparsers.addParser(\n 'c2',\n {aliases:['co'], addHelp:true}\n);\nbar.addArgument(\n [ '-b', '--bar' ],\n {\n action: 'store',\n type: 'int',\n help: 'foo3 bar3'\n }\n);\n\nvar args = parser.parseArgs();\nconsole.dir(args);\n\n```\n\nDetails in [original sub-commands guide](http://docs.python.org/dev/library/argparse.html#sub-commands)\n\n\nContributors\n============\n\n- [Eugene Shkuropat](https://github.com/shkuropat)\n- [Paul Jacobson](https://github.com/hpaulj)\n\n[others](https://github.com/nodeca/argparse/graphs/contributors)\n\nLicense\n=======\n\nCopyright (c) 2012 [Vitaly Puzrin](https://github.com/puzrin).\nReleased under the MIT license. See\n[LICENSE](https://github.com/nodeca/argparse/blob/master/LICENSE) for details.\n\n\n", - "readmeFilename": "README.md", - "_id": "argparse@0.1.15", - "dist": { - "shasum": "28a1f72c43113e763220e5708414301c8840f0a1", - "tarball": "http://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz" - }, - "_from": "argparse@~ 0.1.11", - "_resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.15.tgz", - "_npmVersion": "1.2.18", - "_npmUser": { - "name": "vitaly", - "email": "vitaly@rcdesign.ru" - }, - "maintainers": [ - { - "name": "vitaly", - "email": "vitaly@rcdesign.ru" - } - ], - "directories": {}, - "_shasum": "28a1f72c43113e763220e5708414301c8840f0a1" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/README.md b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/README.md deleted file mode 100644 index a74bd12d..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/README.md +++ /dev/null @@ -1,73 +0,0 @@ -**Esprima** ([esprima.org](http://esprima.org)) is a high performance, -standard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) -parser written in ECMAScript (also popularly known as -[JavaScript](http://en.wikipedia.org/wiki/JavaScript>JavaScript)). -Esprima is created and maintained by [Ariya Hidayat](http://twitter.com/ariyahidayat), -with the help of [many contributors](https://github.com/ariya/esprima/contributors). - -Esprima runs on web browsers (IE 6+, Firefox 1+, Safari 3+, Chrome 1+, Konqueror 4.6+, Opera 8+) as well as -[Node.js](http://nodejs.org). - -### Features - -- Full support for [ECMAScript 5.1](http://www.ecma-international.org/publications/standards/Ecma-262.htm)(ECMA-262) -- Sensible [syntax tree format](http://esprima.org/doc/index.html#ast) compatible with Mozilla -[Parser AST](https://developer.mozilla.org/en/SpiderMonkey/Parser_API) -- Heavily tested (> 550 [unit tests](http://esprima.org/test/) with solid 100% statement coverage) -- Optional tracking of syntax node location (index-based and line-column) -- Experimental support for ES6/Harmony (module, class, destructuring, ...) - -Esprima is blazing fast (see the [benchmark suite](http://esprima.org/test/benchmarks.html)). -It is up to 3x faster than UglifyJS v1 and it is still [competitive](http://esprima.org/test/compare.html) -with the new generation of fast parsers. - -### Applications - -Esprima serves as the basis for many popular JavaScript development tools: - -- Code coverage analysis: [node-cover](https://github.com/itay/node-cover), [Istanbul](https://github.com/yahoo/Istanbul) -- Documentation tool: [JFDoc](https://github.com/thejohnfreeman/jfdoc), [JSDuck](https://github.com/senchalabs/jsduck) -- Language extension: [LLJS](http://mbebenita.github.com/LLJS/) (low-level JS), -[Sweet.js](http://sweetjs.org/) (macro) -- ES6/Harmony transpiler: [Six](https://github.com/matthewrobb/six), [Harmonizr](https://github.com/jdiamond/harmonizr) -- Eclipse Orion smart editing ([outline view](https://github.com/aclement/esprima-outline), [content assist](http://contraptionsforprogramming.blogspot.com/2012/02/better-javascript-content-assist-in.html)) -- Source code modification: [Esmorph](https://github.com/ariya/esmorph), [Code Painter](https://github.com/fawek/codepainter), -- Source transformation: [node-falafel](https://github.com/substack/node-falafel), [Esmangle](https://github.com/Constellation/esmangle), [escodegen](https://github.com/Constellation/escodegen) - -### Questions? -- [Documentation](http://esprima.org/doc) -- [Issue tracker](http://issues.esprima.org): [known problems](http://code.google.com/p/esprima/issues/list?q=Defect) -and [future plans](http://code.google.com/p/esprima/issues/list?q=Enhancement) -- [Mailing list](http://groups.google.com/group/esprima) -- [Contribution guide](http://esprima.org/doc/index.html#contribution) - -Follow [@Esprima](http://twitter.com/Esprima) on Twitter to get the -development updates. -Feedback and contribution are welcomed! - -### License - -Copyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about) - and other contributors. - -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 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/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esparse.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esparse.js deleted file mode 100755 index 3e7bb81e..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esparse.js +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env node -/* - Copyright (C) 2012 Ariya Hidayat - Copyright (C) 2011 Ariya Hidayat - - 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 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. -*/ - -/*jslint sloppy:true node:true rhino:true */ - -var fs, esprima, fname, content, options, syntax; - -if (typeof require === 'function') { - fs = require('fs'); - esprima = require('esprima'); -} else if (typeof load === 'function') { - try { - load('esprima.js'); - } catch (e) { - load('../esprima.js'); - } -} - -// Shims to Node.js objects when running under Rhino. -if (typeof console === 'undefined' && typeof process === 'undefined') { - console = { log: print }; - fs = { readFileSync: readFile }; - process = { argv: arguments, exit: quit }; - process.argv.unshift('esparse.js'); - process.argv.unshift('rhino'); -} - -function showUsage() { - console.log('Usage:'); - console.log(' esparse [options] file.js'); - console.log(); - console.log('Available options:'); - console.log(); - console.log(' --comment Gather all line and block comments in an array'); - console.log(' --loc Include line-column location info for each syntax node'); - console.log(' --range Include index-based range for each syntax node'); - console.log(' --raw Display the raw value of literals'); - console.log(' --tokens List all tokens in an array'); - console.log(' --tolerant Tolerate errors on a best-effort basis (experimental)'); - console.log(' -v, --version Shows program version'); - console.log(); - process.exit(1); -} - -if (process.argv.length <= 2) { - showUsage(); -} - -options = {}; - -process.argv.splice(2).forEach(function (entry) { - - if (entry === '-h' || entry === '--help') { - showUsage(); - } else if (entry === '-v' || entry === '--version') { - console.log('ECMAScript Parser (using Esprima version', esprima.version, ')'); - console.log(); - process.exit(0); - } else if (entry === '--comment') { - options.comment = true; - } else if (entry === '--loc') { - options.loc = true; - } else if (entry === '--range') { - options.range = true; - } else if (entry === '--raw') { - options.raw = true; - } else if (entry === '--tokens') { - options.tokens = true; - } else if (entry === '--tolerant') { - options.tolerant = true; - } else if (entry.slice(0, 2) === '--') { - console.log('Error: unknown option ' + entry + '.'); - process.exit(1); - } else if (typeof fname === 'string') { - console.log('Error: more than one input file.'); - process.exit(1); - } else { - fname = entry; - } -}); - -if (typeof fname !== 'string') { - console.log('Error: no input file.'); - process.exit(1); -} - -try { - content = fs.readFileSync(fname, 'utf-8'); - syntax = esprima.parse(content, options); - console.log(JSON.stringify(syntax, null, 4)); -} catch (e) { - console.log('Error: ' + e.message); - process.exit(1); -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esvalidate.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esvalidate.js deleted file mode 100755 index e0af3f70..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/bin/esvalidate.js +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env node -/* - Copyright (C) 2012 Ariya Hidayat - - 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 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. -*/ - -/*jslint sloppy:true plusplus:true node:true rhino:true */ - -var fs, esprima, options, fnames, count; - -if (typeof require === 'function') { - fs = require('fs'); - esprima = require('esprima'); -} else if (typeof load === 'function') { - try { - load('esprima.js'); - } catch (e) { - load('../esprima.js'); - } -} - -// Shims to Node.js objects when running under Rhino. -if (typeof console === 'undefined' && typeof process === 'undefined') { - console = { log: print }; - fs = { readFileSync: readFile }; - process = { argv: arguments, exit: quit }; - process.argv.unshift('esvalidate.js'); - process.argv.unshift('rhino'); -} - -function showUsage() { - console.log('Usage:'); - console.log(' esvalidate [options] file.js'); - console.log(); - console.log('Available options:'); - console.log(); - console.log(' --format=type Set the report format, plain (default) or junit'); - console.log(' -v, --version Print program version'); - console.log(); - process.exit(1); -} - -if (process.argv.length <= 2) { - showUsage(); -} - -options = { - format: 'plain' -}; - -fnames = []; - -process.argv.splice(2).forEach(function (entry) { - - if (entry === '-h' || entry === '--help') { - showUsage(); - } else if (entry === '-v' || entry === '--version') { - console.log('ECMAScript Validator (using Esprima version', esprima.version, ')'); - console.log(); - process.exit(0); - } else if (entry.slice(0, 9) === '--format=') { - options.format = entry.slice(9); - if (options.format !== 'plain' && options.format !== 'junit') { - console.log('Error: unknown report format ' + options.format + '.'); - process.exit(1); - } - } else if (entry.slice(0, 2) === '--') { - console.log('Error: unknown option ' + entry + '.'); - process.exit(1); - } else { - fnames.push(entry); - } -}); - -if (fnames.length === 0) { - console.log('Error: no input file.'); - process.exit(1); -} - -if (options.format === 'junit') { - console.log(''); - console.log(''); -} - -count = 0; -fnames.forEach(function (fname) { - var content, timestamp, syntax, name; - try { - content = fs.readFileSync(fname, 'utf-8'); - - if (content[0] === '#' && content[1] === '!') { - content = '//' + content.substr(2, content.length); - } - - timestamp = Date.now(); - syntax = esprima.parse(content, { tolerant: true }); - - if (options.format === 'junit') { - - name = fname; - if (name.lastIndexOf('/') >= 0) { - name = name.slice(name.lastIndexOf('/') + 1); - } - - console.log(''); - - syntax.errors.forEach(function (error) { - var msg = error.message; - msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); - console.log(' '); - console.log(' ' + - error.message + '(' + name + ':' + error.lineNumber + ')' + - ''); - console.log(' '); - }); - - console.log(''); - - } else if (options.format === 'plain') { - - syntax.errors.forEach(function (error) { - var msg = error.message; - msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); - msg = fname + ':' + error.lineNumber + ': ' + msg; - console.log(msg); - ++count; - }); - - } - } catch (e) { - ++count; - if (options.format === 'junit') { - console.log(''); - console.log(' '); - console.log(' ' + - e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') + - ')'); - console.log(' '); - console.log(''); - } else { - console.log('Error: ' + e.message); - } - } -}); - -if (options.format === 'junit') { - console.log(''); -} - -if (count > 0) { - process.exit(1); -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/esprima.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/esprima.js deleted file mode 100644 index f1320daf..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/esprima.js +++ /dev/null @@ -1,3908 +0,0 @@ -/* - Copyright (C) 2012 Ariya Hidayat - Copyright (C) 2012 Mathias Bynens - Copyright (C) 2012 Joost-Wim Boekesteijn - Copyright (C) 2012 Kris Kowal - Copyright (C) 2012 Yusuke Suzuki - Copyright (C) 2012 Arpad Borsos - Copyright (C) 2011 Ariya Hidayat - - 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 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. -*/ - -/*jslint bitwise:true plusplus:true */ -/*global esprima:true, define:true, exports:true, window: true, -throwError: true, createLiteral: true, generateStatement: true, -parseAssignmentExpression: true, parseBlock: true, parseExpression: true, -parseFunctionDeclaration: true, parseFunctionExpression: true, -parseFunctionSourceElements: true, parseVariableIdentifier: true, -parseLeftHandSideExpression: true, -parseStatement: true, parseSourceElement: true */ - -(function (root, factory) { - 'use strict'; - - // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, - // Rhino, and plain browser loading. - if (typeof define === 'function' && define.amd) { - define(['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.esprima = {})); - } -}(this, function (exports) { - 'use strict'; - - var Token, - TokenName, - Syntax, - PropertyKind, - Messages, - Regex, - source, - strict, - index, - lineNumber, - lineStart, - length, - buffer, - state, - extra; - - Token = { - BooleanLiteral: 1, - EOF: 2, - Identifier: 3, - Keyword: 4, - NullLiteral: 5, - NumericLiteral: 6, - Punctuator: 7, - StringLiteral: 8 - }; - - TokenName = {}; - TokenName[Token.BooleanLiteral] = 'Boolean'; - TokenName[Token.EOF] = ''; - TokenName[Token.Identifier] = 'Identifier'; - TokenName[Token.Keyword] = 'Keyword'; - TokenName[Token.NullLiteral] = 'Null'; - TokenName[Token.NumericLiteral] = 'Numeric'; - TokenName[Token.Punctuator] = 'Punctuator'; - TokenName[Token.StringLiteral] = 'String'; - - Syntax = { - AssignmentExpression: 'AssignmentExpression', - ArrayExpression: 'ArrayExpression', - BlockStatement: 'BlockStatement', - BinaryExpression: 'BinaryExpression', - BreakStatement: 'BreakStatement', - CallExpression: 'CallExpression', - CatchClause: 'CatchClause', - ConditionalExpression: 'ConditionalExpression', - ContinueStatement: 'ContinueStatement', - DoWhileStatement: 'DoWhileStatement', - DebuggerStatement: 'DebuggerStatement', - EmptyStatement: 'EmptyStatement', - ExpressionStatement: 'ExpressionStatement', - ForStatement: 'ForStatement', - ForInStatement: 'ForInStatement', - FunctionDeclaration: 'FunctionDeclaration', - FunctionExpression: 'FunctionExpression', - Identifier: 'Identifier', - IfStatement: 'IfStatement', - Literal: 'Literal', - LabeledStatement: 'LabeledStatement', - LogicalExpression: 'LogicalExpression', - MemberExpression: 'MemberExpression', - NewExpression: 'NewExpression', - ObjectExpression: 'ObjectExpression', - Program: 'Program', - Property: 'Property', - ReturnStatement: 'ReturnStatement', - SequenceExpression: 'SequenceExpression', - SwitchStatement: 'SwitchStatement', - SwitchCase: 'SwitchCase', - ThisExpression: 'ThisExpression', - ThrowStatement: 'ThrowStatement', - TryStatement: 'TryStatement', - UnaryExpression: 'UnaryExpression', - UpdateExpression: 'UpdateExpression', - VariableDeclaration: 'VariableDeclaration', - VariableDeclarator: 'VariableDeclarator', - WhileStatement: 'WhileStatement', - WithStatement: 'WithStatement' - }; - - PropertyKind = { - Data: 1, - Get: 2, - Set: 4 - }; - - // Error messages should be identical to V8. - Messages = { - UnexpectedToken: 'Unexpected token %0', - UnexpectedNumber: 'Unexpected number', - UnexpectedString: 'Unexpected string', - UnexpectedIdentifier: 'Unexpected identifier', - UnexpectedReserved: 'Unexpected reserved word', - UnexpectedEOS: 'Unexpected end of input', - NewlineAfterThrow: 'Illegal newline after throw', - InvalidRegExp: 'Invalid regular expression', - UnterminatedRegExp: 'Invalid regular expression: missing /', - InvalidLHSInAssignment: 'Invalid left-hand side in assignment', - InvalidLHSInForIn: 'Invalid left-hand side in for-in', - MultipleDefaultsInSwitch: 'More than one default clause in switch statement', - NoCatchOrFinally: 'Missing catch or finally after try', - UnknownLabel: 'Undefined label \'%0\'', - Redeclaration: '%0 \'%1\' has already been declared', - IllegalContinue: 'Illegal continue statement', - IllegalBreak: 'Illegal break statement', - IllegalReturn: 'Illegal return statement', - StrictModeWith: 'Strict mode code may not include a with statement', - StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', - StrictVarName: 'Variable name may not be eval or arguments in strict mode', - StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', - StrictParamDupe: 'Strict mode function may not have duplicate parameter names', - StrictFunctionName: 'Function name may not be eval or arguments in strict mode', - StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', - StrictDelete: 'Delete of an unqualified identifier in strict mode.', - StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', - AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', - AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', - StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', - StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', - StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', - StrictReservedWord: 'Use of future reserved word in strict mode' - }; - - // See also tools/generate-unicode-regex.py. - Regex = { - NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'), - NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]') - }; - - // Ensure the condition is true, otherwise throw an error. - // This is only to have a better contract semantic, i.e. another safety net - // to catch a logic error. The condition shall be fulfilled in normal case. - // Do NOT use this to enforce a certain condition on any user input. - - function assert(condition, message) { - if (!condition) { - throw new Error('ASSERT: ' + message); - } - } - - function sliceSource(from, to) { - return source.slice(from, to); - } - - if (typeof 'esprima'[0] === 'undefined') { - sliceSource = function sliceArraySource(from, to) { - return source.slice(from, to).join(''); - }; - } - - function isDecimalDigit(ch) { - return '0123456789'.indexOf(ch) >= 0; - } - - function isHexDigit(ch) { - return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; - } - - function isOctalDigit(ch) { - return '01234567'.indexOf(ch) >= 0; - } - - - // 7.2 White Space - - function isWhiteSpace(ch) { - return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') || - (ch === '\u000C') || (ch === '\u00A0') || - (ch.charCodeAt(0) >= 0x1680 && - '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0); - } - - // 7.3 Line Terminators - - function isLineTerminator(ch) { - return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029'); - } - - // 7.6 Identifier Names and Identifiers - - function isIdentifierStart(ch) { - return (ch === '$') || (ch === '_') || (ch === '\\') || - (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || - ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch)); - } - - function isIdentifierPart(ch) { - return (ch === '$') || (ch === '_') || (ch === '\\') || - (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || - ((ch >= '0') && (ch <= '9')) || - ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch)); - } - - // 7.6.1.2 Future Reserved Words - - function isFutureReservedWord(id) { - switch (id) { - - // Future reserved words. - case 'class': - case 'enum': - case 'export': - case 'extends': - case 'import': - case 'super': - return true; - } - - return false; - } - - function isStrictModeReservedWord(id) { - switch (id) { - - // Strict Mode reserved words. - case 'implements': - case 'interface': - case 'package': - case 'private': - case 'protected': - case 'public': - case 'static': - case 'yield': - case 'let': - return true; - } - - return false; - } - - function isRestrictedWord(id) { - return id === 'eval' || id === 'arguments'; - } - - // 7.6.1.1 Keywords - - function isKeyword(id) { - var keyword = false; - switch (id.length) { - case 2: - keyword = (id === 'if') || (id === 'in') || (id === 'do'); - break; - case 3: - keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try'); - break; - case 4: - keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with'); - break; - case 5: - keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw'); - break; - case 6: - keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch'); - break; - case 7: - keyword = (id === 'default') || (id === 'finally'); - break; - case 8: - keyword = (id === 'function') || (id === 'continue') || (id === 'debugger'); - break; - case 10: - keyword = (id === 'instanceof'); - break; - } - - if (keyword) { - return true; - } - - switch (id) { - // Future reserved words. - // 'const' is specialized as Keyword in V8. - case 'const': - return true; - - // For compatiblity to SpiderMonkey and ES.next - case 'yield': - case 'let': - return true; - } - - if (strict && isStrictModeReservedWord(id)) { - return true; - } - - return isFutureReservedWord(id); - } - - // 7.4 Comments - - function skipComment() { - var ch, blockComment, lineComment; - - blockComment = false; - lineComment = false; - - while (index < length) { - ch = source[index]; - - if (lineComment) { - ch = source[index++]; - if (isLineTerminator(ch)) { - lineComment = false; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - } - } else if (blockComment) { - if (isLineTerminator(ch)) { - if (ch === '\r' && source[index + 1] === '\n') { - ++index; - } - ++lineNumber; - ++index; - lineStart = index; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - ch = source[index++]; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - if (ch === '*') { - ch = source[index]; - if (ch === '/') { - ++index; - blockComment = false; - } - } - } - } else if (ch === '/') { - ch = source[index + 1]; - if (ch === '/') { - index += 2; - lineComment = true; - } else if (ch === '*') { - index += 2; - blockComment = true; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - break; - } - } else if (isWhiteSpace(ch)) { - ++index; - } else if (isLineTerminator(ch)) { - ++index; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - } else { - break; - } - } - } - - function scanHexEscape(prefix) { - var i, len, ch, code = 0; - - len = (prefix === 'u') ? 4 : 2; - for (i = 0; i < len; ++i) { - if (index < length && isHexDigit(source[index])) { - ch = source[index++]; - code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); - } else { - return ''; - } - } - return String.fromCharCode(code); - } - - function scanIdentifier() { - var ch, start, id, restore; - - ch = source[index]; - if (!isIdentifierStart(ch)) { - return; - } - - start = index; - if (ch === '\\') { - ++index; - if (source[index] !== 'u') { - return; - } - ++index; - restore = index; - ch = scanHexEscape('u'); - if (ch) { - if (ch === '\\' || !isIdentifierStart(ch)) { - return; - } - id = ch; - } else { - index = restore; - id = 'u'; - } - } else { - id = source[index++]; - } - - while (index < length) { - ch = source[index]; - if (!isIdentifierPart(ch)) { - break; - } - if (ch === '\\') { - ++index; - if (source[index] !== 'u') { - return; - } - ++index; - restore = index; - ch = scanHexEscape('u'); - if (ch) { - if (ch === '\\' || !isIdentifierPart(ch)) { - return; - } - id += ch; - } else { - index = restore; - id += 'u'; - } - } else { - id += source[index++]; - } - } - - // There is no keyword or literal with only one character. - // Thus, it must be an identifier. - if (id.length === 1) { - return { - type: Token.Identifier, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (isKeyword(id)) { - return { - type: Token.Keyword, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 7.8.1 Null Literals - - if (id === 'null') { - return { - type: Token.NullLiteral, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 7.8.2 Boolean Literals - - if (id === 'true' || id === 'false') { - return { - type: Token.BooleanLiteral, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - return { - type: Token.Identifier, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 7.7 Punctuators - - function scanPunctuator() { - var start = index, - ch1 = source[index], - ch2, - ch3, - ch4; - - // Check for most common single-character punctuators. - - if (ch1 === ';' || ch1 === '{' || ch1 === '}') { - ++index; - return { - type: Token.Punctuator, - value: ch1, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === ',' || ch1 === '(' || ch1 === ')') { - ++index; - return { - type: Token.Punctuator, - value: ch1, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // Dot (.) can also start a floating-point number, hence the need - // to check the next character. - - ch2 = source[index + 1]; - if (ch1 === '.' && !isDecimalDigit(ch2)) { - return { - type: Token.Punctuator, - value: source[index++], - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // Peek more characters. - - ch3 = source[index + 2]; - ch4 = source[index + 3]; - - // 4-character punctuator: >>>= - - if (ch1 === '>' && ch2 === '>' && ch3 === '>') { - if (ch4 === '=') { - index += 4; - return { - type: Token.Punctuator, - value: '>>>=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - } - - // 3-character punctuators: === !== >>> <<= >>= - - if (ch1 === '=' && ch2 === '=' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '===', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '!' && ch2 === '=' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '!==', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '>' && ch2 === '>' && ch3 === '>') { - index += 3; - return { - type: Token.Punctuator, - value: '>>>', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '<' && ch2 === '<' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '<<=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '>' && ch2 === '>' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '>>=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 2-character punctuators: <= >= == != ++ -- << >> && || - // += -= *= %= &= |= ^= /= - - if (ch2 === '=') { - if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { - index += 2; - return { - type: Token.Punctuator, - value: ch1 + ch2, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - } - - if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) { - if ('+-<>&|'.indexOf(ch2) >= 0) { - index += 2; - return { - type: Token.Punctuator, - value: ch1 + ch2, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - } - - // The remaining 1-character punctuators. - - if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) { - return { - type: Token.Punctuator, - value: source[index++], - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - } - - // 7.8.3 Numeric Literals - - function scanNumericLiteral() { - var number, start, ch; - - ch = source[index]; - assert(isDecimalDigit(ch) || (ch === '.'), - 'Numeric literal must start with a decimal digit or a decimal point'); - - start = index; - number = ''; - if (ch !== '.') { - number = source[index++]; - ch = source[index]; - - // Hex number starts with '0x'. - // Octal number starts with '0'. - if (number === '0') { - if (ch === 'x' || ch === 'X') { - number += source[index++]; - while (index < length) { - ch = source[index]; - if (!isHexDigit(ch)) { - break; - } - number += source[index++]; - } - - if (number.length <= 2) { - // only 0x - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (index < length) { - ch = source[index]; - if (isIdentifierStart(ch)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - return { - type: Token.NumericLiteral, - value: parseInt(number, 16), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } else if (isOctalDigit(ch)) { - number += source[index++]; - while (index < length) { - ch = source[index]; - if (!isOctalDigit(ch)) { - break; - } - number += source[index++]; - } - - if (index < length) { - ch = source[index]; - if (isIdentifierStart(ch) || isDecimalDigit(ch)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - return { - type: Token.NumericLiteral, - value: parseInt(number, 8), - octal: true, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // decimal number starts with '0' such as '09' is illegal. - if (isDecimalDigit(ch)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - while (index < length) { - ch = source[index]; - if (!isDecimalDigit(ch)) { - break; - } - number += source[index++]; - } - } - - if (ch === '.') { - number += source[index++]; - while (index < length) { - ch = source[index]; - if (!isDecimalDigit(ch)) { - break; - } - number += source[index++]; - } - } - - if (ch === 'e' || ch === 'E') { - number += source[index++]; - - ch = source[index]; - if (ch === '+' || ch === '-') { - number += source[index++]; - } - - ch = source[index]; - if (isDecimalDigit(ch)) { - number += source[index++]; - while (index < length) { - ch = source[index]; - if (!isDecimalDigit(ch)) { - break; - } - number += source[index++]; - } - } else { - ch = 'character ' + ch; - if (index >= length) { - ch = ''; - } - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - if (index < length) { - ch = source[index]; - if (isIdentifierStart(ch)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - return { - type: Token.NumericLiteral, - value: parseFloat(number), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 7.8.4 String Literals - - function scanStringLiteral() { - var str = '', quote, start, ch, code, unescaped, restore, octal = false; - - quote = source[index]; - assert((quote === '\'' || quote === '"'), - 'String literal must starts with a quote'); - - start = index; - ++index; - - while (index < length) { - ch = source[index++]; - - if (ch === quote) { - quote = ''; - break; - } else if (ch === '\\') { - ch = source[index++]; - if (!isLineTerminator(ch)) { - switch (ch) { - case 'n': - str += '\n'; - break; - case 'r': - str += '\r'; - break; - case 't': - str += '\t'; - break; - case 'u': - case 'x': - restore = index; - unescaped = scanHexEscape(ch); - if (unescaped) { - str += unescaped; - } else { - index = restore; - str += ch; - } - break; - case 'b': - str += '\b'; - break; - case 'f': - str += '\f'; - break; - case 'v': - str += '\x0B'; - break; - - default: - if (isOctalDigit(ch)) { - code = '01234567'.indexOf(ch); - - // \0 is not octal escape sequence - if (code !== 0) { - octal = true; - } - - if (index < length && isOctalDigit(source[index])) { - octal = true; - code = code * 8 + '01234567'.indexOf(source[index++]); - - // 3 digits are only allowed when string starts - // with 0, 1, 2, 3 - if ('0123'.indexOf(ch) >= 0 && - index < length && - isOctalDigit(source[index])) { - code = code * 8 + '01234567'.indexOf(source[index++]); - } - } - str += String.fromCharCode(code); - } else { - str += ch; - } - break; - } - } else { - ++lineNumber; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - } - } else if (isLineTerminator(ch)) { - break; - } else { - str += ch; - } - } - - if (quote !== '') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.StringLiteral, - value: str, - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanRegExp() { - var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false; - - buffer = null; - skipComment(); - - start = index; - ch = source[index]; - assert(ch === '/', 'Regular expression literal must start with a slash'); - str = source[index++]; - - while (index < length) { - ch = source[index++]; - str += ch; - if (ch === '\\') { - ch = source[index++]; - // ECMA-262 7.8.5 - if (isLineTerminator(ch)) { - throwError({}, Messages.UnterminatedRegExp); - } - str += ch; - } else if (classMarker) { - if (ch === ']') { - classMarker = false; - } - } else { - if (ch === '/') { - terminated = true; - break; - } else if (ch === '[') { - classMarker = true; - } else if (isLineTerminator(ch)) { - throwError({}, Messages.UnterminatedRegExp); - } - } - } - - if (!terminated) { - throwError({}, Messages.UnterminatedRegExp); - } - - // Exclude leading and trailing slash. - pattern = str.substr(1, str.length - 2); - - flags = ''; - while (index < length) { - ch = source[index]; - if (!isIdentifierPart(ch)) { - break; - } - - ++index; - if (ch === '\\' && index < length) { - ch = source[index]; - if (ch === 'u') { - ++index; - restore = index; - ch = scanHexEscape('u'); - if (ch) { - flags += ch; - str += '\\u'; - for (; restore < index; ++restore) { - str += source[restore]; - } - } else { - index = restore; - flags += 'u'; - str += '\\u'; - } - } else { - str += '\\'; - } - } else { - flags += ch; - str += ch; - } - } - - try { - value = new RegExp(pattern, flags); - } catch (e) { - throwError({}, Messages.InvalidRegExp); - } - - return { - literal: str, - value: value, - range: [start, index] - }; - } - - function isIdentifierName(token) { - return token.type === Token.Identifier || - token.type === Token.Keyword || - token.type === Token.BooleanLiteral || - token.type === Token.NullLiteral; - } - - function advance() { - var ch, token; - - skipComment(); - - if (index >= length) { - return { - type: Token.EOF, - lineNumber: lineNumber, - lineStart: lineStart, - range: [index, index] - }; - } - - token = scanPunctuator(); - if (typeof token !== 'undefined') { - return token; - } - - ch = source[index]; - - if (ch === '\'' || ch === '"') { - return scanStringLiteral(); - } - - if (ch === '.' || isDecimalDigit(ch)) { - return scanNumericLiteral(); - } - - token = scanIdentifier(); - if (typeof token !== 'undefined') { - return token; - } - - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - function lex() { - var token; - - if (buffer) { - index = buffer.range[1]; - lineNumber = buffer.lineNumber; - lineStart = buffer.lineStart; - token = buffer; - buffer = null; - return token; - } - - buffer = null; - return advance(); - } - - function lookahead() { - var pos, line, start; - - if (buffer !== null) { - return buffer; - } - - pos = index; - line = lineNumber; - start = lineStart; - buffer = advance(); - index = pos; - lineNumber = line; - lineStart = start; - - return buffer; - } - - // Return true if there is a line terminator before the next token. - - function peekLineTerminator() { - var pos, line, start, found; - - pos = index; - line = lineNumber; - start = lineStart; - skipComment(); - found = lineNumber !== line; - index = pos; - lineNumber = line; - lineStart = start; - - return found; - } - - // Throw an exception - - function throwError(token, messageFormat) { - var error, - args = Array.prototype.slice.call(arguments, 2), - msg = messageFormat.replace( - /%(\d)/g, - function (whole, index) { - return args[index] || ''; - } - ); - - if (typeof token.lineNumber === 'number') { - error = new Error('Line ' + token.lineNumber + ': ' + msg); - error.index = token.range[0]; - error.lineNumber = token.lineNumber; - error.column = token.range[0] - lineStart + 1; - } else { - error = new Error('Line ' + lineNumber + ': ' + msg); - error.index = index; - error.lineNumber = lineNumber; - error.column = index - lineStart + 1; - } - - throw error; - } - - function throwErrorTolerant() { - try { - throwError.apply(null, arguments); - } catch (e) { - if (extra.errors) { - extra.errors.push(e); - } else { - throw e; - } - } - } - - - // Throw an exception because of the token. - - function throwUnexpected(token) { - if (token.type === Token.EOF) { - throwError(token, Messages.UnexpectedEOS); - } - - if (token.type === Token.NumericLiteral) { - throwError(token, Messages.UnexpectedNumber); - } - - if (token.type === Token.StringLiteral) { - throwError(token, Messages.UnexpectedString); - } - - if (token.type === Token.Identifier) { - throwError(token, Messages.UnexpectedIdentifier); - } - - if (token.type === Token.Keyword) { - if (isFutureReservedWord(token.value)) { - throwError(token, Messages.UnexpectedReserved); - } else if (strict && isStrictModeReservedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictReservedWord); - return; - } - throwError(token, Messages.UnexpectedToken, token.value); - } - - // BooleanLiteral, NullLiteral, or Punctuator. - throwError(token, Messages.UnexpectedToken, token.value); - } - - // Expect the next token to match the specified punctuator. - // If not, an exception will be thrown. - - function expect(value) { - var token = lex(); - if (token.type !== Token.Punctuator || token.value !== value) { - throwUnexpected(token); - } - } - - // Expect the next token to match the specified keyword. - // If not, an exception will be thrown. - - function expectKeyword(keyword) { - var token = lex(); - if (token.type !== Token.Keyword || token.value !== keyword) { - throwUnexpected(token); - } - } - - // Return true if the next token matches the specified punctuator. - - function match(value) { - var token = lookahead(); - return token.type === Token.Punctuator && token.value === value; - } - - // Return true if the next token matches the specified keyword - - function matchKeyword(keyword) { - var token = lookahead(); - return token.type === Token.Keyword && token.value === keyword; - } - - // Return true if the next token is an assignment operator - - function matchAssign() { - var token = lookahead(), - op = token.value; - - if (token.type !== Token.Punctuator) { - return false; - } - return op === '=' || - op === '*=' || - op === '/=' || - op === '%=' || - op === '+=' || - op === '-=' || - op === '<<=' || - op === '>>=' || - op === '>>>=' || - op === '&=' || - op === '^=' || - op === '|='; - } - - function consumeSemicolon() { - var token, line; - - // Catch the very common case first. - if (source[index] === ';') { - lex(); - return; - } - - line = lineNumber; - skipComment(); - if (lineNumber !== line) { - return; - } - - if (match(';')) { - lex(); - return; - } - - token = lookahead(); - if (token.type !== Token.EOF && !match('}')) { - throwUnexpected(token); - } - } - - // Return true if provided expression is LeftHandSideExpression - - function isLeftHandSide(expr) { - return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; - } - - // 11.1.4 Array Initialiser - - function parseArrayInitialiser() { - var elements = []; - - expect('['); - - while (!match(']')) { - if (match(',')) { - lex(); - elements.push(null); - } else { - elements.push(parseAssignmentExpression()); - - if (!match(']')) { - expect(','); - } - } - } - - expect(']'); - - return { - type: Syntax.ArrayExpression, - elements: elements - }; - } - - // 11.1.5 Object Initialiser - - function parsePropertyFunction(param, first) { - var previousStrict, body; - - previousStrict = strict; - body = parseFunctionSourceElements(); - if (first && strict && isRestrictedWord(param[0].name)) { - throwErrorTolerant(first, Messages.StrictParamName); - } - strict = previousStrict; - - return { - type: Syntax.FunctionExpression, - id: null, - params: param, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }; - } - - function parseObjectPropertyKey() { - var token = lex(); - - // Note: This function is called only from parseObjectProperty(), where - // EOF and Punctuator tokens are already filtered out. - - if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { - if (strict && token.octal) { - throwErrorTolerant(token, Messages.StrictOctalLiteral); - } - return createLiteral(token); - } - - return { - type: Syntax.Identifier, - name: token.value - }; - } - - function parseObjectProperty() { - var token, key, id, param; - - token = lookahead(); - - if (token.type === Token.Identifier) { - - id = parseObjectPropertyKey(); - - // Property Assignment: Getter and Setter. - - if (token.value === 'get' && !match(':')) { - key = parseObjectPropertyKey(); - expect('('); - expect(')'); - return { - type: Syntax.Property, - key: key, - value: parsePropertyFunction([]), - kind: 'get' - }; - } else if (token.value === 'set' && !match(':')) { - key = parseObjectPropertyKey(); - expect('('); - token = lookahead(); - if (token.type !== Token.Identifier) { - expect(')'); - throwErrorTolerant(token, Messages.UnexpectedToken, token.value); - return { - type: Syntax.Property, - key: key, - value: parsePropertyFunction([]), - kind: 'set' - }; - } else { - param = [ parseVariableIdentifier() ]; - expect(')'); - return { - type: Syntax.Property, - key: key, - value: parsePropertyFunction(param, token), - kind: 'set' - }; - } - } else { - expect(':'); - return { - type: Syntax.Property, - key: id, - value: parseAssignmentExpression(), - kind: 'init' - }; - } - } else if (token.type === Token.EOF || token.type === Token.Punctuator) { - throwUnexpected(token); - } else { - key = parseObjectPropertyKey(); - expect(':'); - return { - type: Syntax.Property, - key: key, - value: parseAssignmentExpression(), - kind: 'init' - }; - } - } - - function parseObjectInitialiser() { - var properties = [], property, name, kind, map = {}, toString = String; - - expect('{'); - - while (!match('}')) { - property = parseObjectProperty(); - - if (property.key.type === Syntax.Identifier) { - name = property.key.name; - } else { - name = toString(property.key.value); - } - kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; - if (Object.prototype.hasOwnProperty.call(map, name)) { - if (map[name] === PropertyKind.Data) { - if (strict && kind === PropertyKind.Data) { - throwErrorTolerant({}, Messages.StrictDuplicateProperty); - } else if (kind !== PropertyKind.Data) { - throwErrorTolerant({}, Messages.AccessorDataProperty); - } - } else { - if (kind === PropertyKind.Data) { - throwErrorTolerant({}, Messages.AccessorDataProperty); - } else if (map[name] & kind) { - throwErrorTolerant({}, Messages.AccessorGetSet); - } - } - map[name] |= kind; - } else { - map[name] = kind; - } - - properties.push(property); - - if (!match('}')) { - expect(','); - } - } - - expect('}'); - - return { - type: Syntax.ObjectExpression, - properties: properties - }; - } - - // 11.1.6 The Grouping Operator - - function parseGroupExpression() { - var expr; - - expect('('); - - expr = parseExpression(); - - expect(')'); - - return expr; - } - - - // 11.1 Primary Expressions - - function parsePrimaryExpression() { - var token = lookahead(), - type = token.type; - - if (type === Token.Identifier) { - return { - type: Syntax.Identifier, - name: lex().value - }; - } - - if (type === Token.StringLiteral || type === Token.NumericLiteral) { - if (strict && token.octal) { - throwErrorTolerant(token, Messages.StrictOctalLiteral); - } - return createLiteral(lex()); - } - - if (type === Token.Keyword) { - if (matchKeyword('this')) { - lex(); - return { - type: Syntax.ThisExpression - }; - } - - if (matchKeyword('function')) { - return parseFunctionExpression(); - } - } - - if (type === Token.BooleanLiteral) { - lex(); - token.value = (token.value === 'true'); - return createLiteral(token); - } - - if (type === Token.NullLiteral) { - lex(); - token.value = null; - return createLiteral(token); - } - - if (match('[')) { - return parseArrayInitialiser(); - } - - if (match('{')) { - return parseObjectInitialiser(); - } - - if (match('(')) { - return parseGroupExpression(); - } - - if (match('/') || match('/=')) { - return createLiteral(scanRegExp()); - } - - return throwUnexpected(lex()); - } - - // 11.2 Left-Hand-Side Expressions - - function parseArguments() { - var args = []; - - expect('('); - - if (!match(')')) { - while (index < length) { - args.push(parseAssignmentExpression()); - if (match(')')) { - break; - } - expect(','); - } - } - - expect(')'); - - return args; - } - - function parseNonComputedProperty() { - var token = lex(); - - if (!isIdentifierName(token)) { - throwUnexpected(token); - } - - return { - type: Syntax.Identifier, - name: token.value - }; - } - - function parseNonComputedMember() { - expect('.'); - - return parseNonComputedProperty(); - } - - function parseComputedMember() { - var expr; - - expect('['); - - expr = parseExpression(); - - expect(']'); - - return expr; - } - - function parseNewExpression() { - var expr; - - expectKeyword('new'); - - expr = { - type: Syntax.NewExpression, - callee: parseLeftHandSideExpression(), - 'arguments': [] - }; - - if (match('(')) { - expr['arguments'] = parseArguments(); - } - - return expr; - } - - function parseLeftHandSideExpressionAllowCall() { - var expr; - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[') || match('(')) { - if (match('(')) { - expr = { - type: Syntax.CallExpression, - callee: expr, - 'arguments': parseArguments() - }; - } else if (match('[')) { - expr = { - type: Syntax.MemberExpression, - computed: true, - object: expr, - property: parseComputedMember() - }; - } else { - expr = { - type: Syntax.MemberExpression, - computed: false, - object: expr, - property: parseNonComputedMember() - }; - } - } - - return expr; - } - - - function parseLeftHandSideExpression() { - var expr; - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[')) { - if (match('[')) { - expr = { - type: Syntax.MemberExpression, - computed: true, - object: expr, - property: parseComputedMember() - }; - } else { - expr = { - type: Syntax.MemberExpression, - computed: false, - object: expr, - property: parseNonComputedMember() - }; - } - } - - return expr; - } - - // 11.3 Postfix Expressions - - function parsePostfixExpression() { - var expr = parseLeftHandSideExpressionAllowCall(), token; - - token = lookahead(); - if (token.type !== Token.Punctuator) { - return expr; - } - - if ((match('++') || match('--')) && !peekLineTerminator()) { - // 11.3.1, 11.3.2 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant({}, Messages.StrictLHSPostfix); - } - if (!isLeftHandSide(expr)) { - throwErrorTolerant({}, Messages.InvalidLHSInAssignment); - } - - expr = { - type: Syntax.UpdateExpression, - operator: lex().value, - argument: expr, - prefix: false - }; - } - - return expr; - } - - // 11.4 Unary Operators - - function parseUnaryExpression() { - var token, expr; - - token = lookahead(); - if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { - return parsePostfixExpression(); - } - - if (match('++') || match('--')) { - token = lex(); - expr = parseUnaryExpression(); - // 11.4.4, 11.4.5 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant({}, Messages.StrictLHSPrefix); - } - - if (!isLeftHandSide(expr)) { - throwErrorTolerant({}, Messages.InvalidLHSInAssignment); - } - - expr = { - type: Syntax.UpdateExpression, - operator: token.value, - argument: expr, - prefix: true - }; - return expr; - } - - if (match('+') || match('-') || match('~') || match('!')) { - expr = { - type: Syntax.UnaryExpression, - operator: lex().value, - argument: parseUnaryExpression(), - prefix: true - }; - return expr; - } - - if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { - expr = { - type: Syntax.UnaryExpression, - operator: lex().value, - argument: parseUnaryExpression(), - prefix: true - }; - if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { - throwErrorTolerant({}, Messages.StrictDelete); - } - return expr; - } - - return parsePostfixExpression(); - } - - // 11.5 Multiplicative Operators - - function parseMultiplicativeExpression() { - var expr = parseUnaryExpression(); - - while (match('*') || match('/') || match('%')) { - expr = { - type: Syntax.BinaryExpression, - operator: lex().value, - left: expr, - right: parseUnaryExpression() - }; - } - - return expr; - } - - // 11.6 Additive Operators - - function parseAdditiveExpression() { - var expr = parseMultiplicativeExpression(); - - while (match('+') || match('-')) { - expr = { - type: Syntax.BinaryExpression, - operator: lex().value, - left: expr, - right: parseMultiplicativeExpression() - }; - } - - return expr; - } - - // 11.7 Bitwise Shift Operators - - function parseShiftExpression() { - var expr = parseAdditiveExpression(); - - while (match('<<') || match('>>') || match('>>>')) { - expr = { - type: Syntax.BinaryExpression, - operator: lex().value, - left: expr, - right: parseAdditiveExpression() - }; - } - - return expr; - } - // 11.8 Relational Operators - - function parseRelationalExpression() { - var expr, previousAllowIn; - - previousAllowIn = state.allowIn; - state.allowIn = true; - - expr = parseShiftExpression(); - - while (match('<') || match('>') || match('<=') || match('>=') || (previousAllowIn && matchKeyword('in')) || matchKeyword('instanceof')) { - expr = { - type: Syntax.BinaryExpression, - operator: lex().value, - left: expr, - right: parseShiftExpression() - }; - } - - state.allowIn = previousAllowIn; - return expr; - } - - // 11.9 Equality Operators - - function parseEqualityExpression() { - var expr = parseRelationalExpression(); - - while (match('==') || match('!=') || match('===') || match('!==')) { - expr = { - type: Syntax.BinaryExpression, - operator: lex().value, - left: expr, - right: parseRelationalExpression() - }; - } - - return expr; - } - - // 11.10 Binary Bitwise Operators - - function parseBitwiseANDExpression() { - var expr = parseEqualityExpression(); - - while (match('&')) { - lex(); - expr = { - type: Syntax.BinaryExpression, - operator: '&', - left: expr, - right: parseEqualityExpression() - }; - } - - return expr; - } - - function parseBitwiseXORExpression() { - var expr = parseBitwiseANDExpression(); - - while (match('^')) { - lex(); - expr = { - type: Syntax.BinaryExpression, - operator: '^', - left: expr, - right: parseBitwiseANDExpression() - }; - } - - return expr; - } - - function parseBitwiseORExpression() { - var expr = parseBitwiseXORExpression(); - - while (match('|')) { - lex(); - expr = { - type: Syntax.BinaryExpression, - operator: '|', - left: expr, - right: parseBitwiseXORExpression() - }; - } - - return expr; - } - - // 11.11 Binary Logical Operators - - function parseLogicalANDExpression() { - var expr = parseBitwiseORExpression(); - - while (match('&&')) { - lex(); - expr = { - type: Syntax.LogicalExpression, - operator: '&&', - left: expr, - right: parseBitwiseORExpression() - }; - } - - return expr; - } - - function parseLogicalORExpression() { - var expr = parseLogicalANDExpression(); - - while (match('||')) { - lex(); - expr = { - type: Syntax.LogicalExpression, - operator: '||', - left: expr, - right: parseLogicalANDExpression() - }; - } - - return expr; - } - - // 11.12 Conditional Operator - - function parseConditionalExpression() { - var expr, previousAllowIn, consequent; - - expr = parseLogicalORExpression(); - - if (match('?')) { - lex(); - previousAllowIn = state.allowIn; - state.allowIn = true; - consequent = parseAssignmentExpression(); - state.allowIn = previousAllowIn; - expect(':'); - - expr = { - type: Syntax.ConditionalExpression, - test: expr, - consequent: consequent, - alternate: parseAssignmentExpression() - }; - } - - return expr; - } - - // 11.13 Assignment Operators - - function parseAssignmentExpression() { - var token, expr; - - token = lookahead(); - expr = parseConditionalExpression(); - - if (matchAssign()) { - // LeftHandSideExpression - if (!isLeftHandSide(expr)) { - throwErrorTolerant({}, Messages.InvalidLHSInAssignment); - } - - // 11.13.1 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant(token, Messages.StrictLHSAssignment); - } - - expr = { - type: Syntax.AssignmentExpression, - operator: lex().value, - left: expr, - right: parseAssignmentExpression() - }; - } - - return expr; - } - - // 11.14 Comma Operator - - function parseExpression() { - var expr = parseAssignmentExpression(); - - if (match(',')) { - expr = { - type: Syntax.SequenceExpression, - expressions: [ expr ] - }; - - while (index < length) { - if (!match(',')) { - break; - } - lex(); - expr.expressions.push(parseAssignmentExpression()); - } - - } - return expr; - } - - // 12.1 Block - - function parseStatementList() { - var list = [], - statement; - - while (index < length) { - if (match('}')) { - break; - } - statement = parseSourceElement(); - if (typeof statement === 'undefined') { - break; - } - list.push(statement); - } - - return list; - } - - function parseBlock() { - var block; - - expect('{'); - - block = parseStatementList(); - - expect('}'); - - return { - type: Syntax.BlockStatement, - body: block - }; - } - - // 12.2 Variable Statement - - function parseVariableIdentifier() { - var token = lex(); - - if (token.type !== Token.Identifier) { - throwUnexpected(token); - } - - return { - type: Syntax.Identifier, - name: token.value - }; - } - - function parseVariableDeclaration(kind) { - var id = parseVariableIdentifier(), - init = null; - - // 12.2.1 - if (strict && isRestrictedWord(id.name)) { - throwErrorTolerant({}, Messages.StrictVarName); - } - - if (kind === 'const') { - expect('='); - init = parseAssignmentExpression(); - } else if (match('=')) { - lex(); - init = parseAssignmentExpression(); - } - - return { - type: Syntax.VariableDeclarator, - id: id, - init: init - }; - } - - function parseVariableDeclarationList(kind) { - var list = []; - - do { - list.push(parseVariableDeclaration(kind)); - if (!match(',')) { - break; - } - lex(); - } while (index < length); - - return list; - } - - function parseVariableStatement() { - var declarations; - - expectKeyword('var'); - - declarations = parseVariableDeclarationList(); - - consumeSemicolon(); - - return { - type: Syntax.VariableDeclaration, - declarations: declarations, - kind: 'var' - }; - } - - // kind may be `const` or `let` - // Both are experimental and not in the specification yet. - // see http://wiki.ecmascript.org/doku.php?id=harmony:const - // and http://wiki.ecmascript.org/doku.php?id=harmony:let - function parseConstLetDeclaration(kind) { - var declarations; - - expectKeyword(kind); - - declarations = parseVariableDeclarationList(kind); - - consumeSemicolon(); - - return { - type: Syntax.VariableDeclaration, - declarations: declarations, - kind: kind - }; - } - - // 12.3 Empty Statement - - function parseEmptyStatement() { - expect(';'); - - return { - type: Syntax.EmptyStatement - }; - } - - // 12.4 Expression Statement - - function parseExpressionStatement() { - var expr = parseExpression(); - - consumeSemicolon(); - - return { - type: Syntax.ExpressionStatement, - expression: expr - }; - } - - // 12.5 If statement - - function parseIfStatement() { - var test, consequent, alternate; - - expectKeyword('if'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - consequent = parseStatement(); - - if (matchKeyword('else')) { - lex(); - alternate = parseStatement(); - } else { - alternate = null; - } - - return { - type: Syntax.IfStatement, - test: test, - consequent: consequent, - alternate: alternate - }; - } - - // 12.6 Iteration Statements - - function parseDoWhileStatement() { - var body, test, oldInIteration; - - expectKeyword('do'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - expectKeyword('while'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - if (match(';')) { - lex(); - } - - return { - type: Syntax.DoWhileStatement, - body: body, - test: test - }; - } - - function parseWhileStatement() { - var test, body, oldInIteration; - - expectKeyword('while'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - return { - type: Syntax.WhileStatement, - test: test, - body: body - }; - } - - function parseForVariableDeclaration() { - var token = lex(); - - return { - type: Syntax.VariableDeclaration, - declarations: parseVariableDeclarationList(), - kind: token.value - }; - } - - function parseForStatement() { - var init, test, update, left, right, body, oldInIteration; - - init = test = update = null; - - expectKeyword('for'); - - expect('('); - - if (match(';')) { - lex(); - } else { - if (matchKeyword('var') || matchKeyword('let')) { - state.allowIn = false; - init = parseForVariableDeclaration(); - state.allowIn = true; - - if (init.declarations.length === 1 && matchKeyword('in')) { - lex(); - left = init; - right = parseExpression(); - init = null; - } - } else { - state.allowIn = false; - init = parseExpression(); - state.allowIn = true; - - if (matchKeyword('in')) { - // LeftHandSideExpression - if (!isLeftHandSide(init)) { - throwErrorTolerant({}, Messages.InvalidLHSInForIn); - } - - lex(); - left = init; - right = parseExpression(); - init = null; - } - } - - if (typeof left === 'undefined') { - expect(';'); - } - } - - if (typeof left === 'undefined') { - - if (!match(';')) { - test = parseExpression(); - } - expect(';'); - - if (!match(')')) { - update = parseExpression(); - } - } - - expect(')'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - if (typeof left === 'undefined') { - return { - type: Syntax.ForStatement, - init: init, - test: test, - update: update, - body: body - }; - } - - return { - type: Syntax.ForInStatement, - left: left, - right: right, - body: body, - each: false - }; - } - - // 12.7 The continue statement - - function parseContinueStatement() { - var token, label = null; - - expectKeyword('continue'); - - // Optimize the most common form: 'continue;'. - if (source[index] === ';') { - lex(); - - if (!state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return { - type: Syntax.ContinueStatement, - label: null - }; - } - - if (peekLineTerminator()) { - if (!state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return { - type: Syntax.ContinueStatement, - label: null - }; - } - - token = lookahead(); - if (token.type === Token.Identifier) { - label = parseVariableIdentifier(); - - if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) { - throwError({}, Messages.UnknownLabel, label.name); - } - } - - consumeSemicolon(); - - if (label === null && !state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return { - type: Syntax.ContinueStatement, - label: label - }; - } - - // 12.8 The break statement - - function parseBreakStatement() { - var token, label = null; - - expectKeyword('break'); - - // Optimize the most common form: 'break;'. - if (source[index] === ';') { - lex(); - - if (!(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return { - type: Syntax.BreakStatement, - label: null - }; - } - - if (peekLineTerminator()) { - if (!(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return { - type: Syntax.BreakStatement, - label: null - }; - } - - token = lookahead(); - if (token.type === Token.Identifier) { - label = parseVariableIdentifier(); - - if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) { - throwError({}, Messages.UnknownLabel, label.name); - } - } - - consumeSemicolon(); - - if (label === null && !(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return { - type: Syntax.BreakStatement, - label: label - }; - } - - // 12.9 The return statement - - function parseReturnStatement() { - var token, argument = null; - - expectKeyword('return'); - - if (!state.inFunctionBody) { - throwErrorTolerant({}, Messages.IllegalReturn); - } - - // 'return' followed by a space and an identifier is very common. - if (source[index] === ' ') { - if (isIdentifierStart(source[index + 1])) { - argument = parseExpression(); - consumeSemicolon(); - return { - type: Syntax.ReturnStatement, - argument: argument - }; - } - } - - if (peekLineTerminator()) { - return { - type: Syntax.ReturnStatement, - argument: null - }; - } - - if (!match(';')) { - token = lookahead(); - if (!match('}') && token.type !== Token.EOF) { - argument = parseExpression(); - } - } - - consumeSemicolon(); - - return { - type: Syntax.ReturnStatement, - argument: argument - }; - } - - // 12.10 The with statement - - function parseWithStatement() { - var object, body; - - if (strict) { - throwErrorTolerant({}, Messages.StrictModeWith); - } - - expectKeyword('with'); - - expect('('); - - object = parseExpression(); - - expect(')'); - - body = parseStatement(); - - return { - type: Syntax.WithStatement, - object: object, - body: body - }; - } - - // 12.10 The swith statement - - function parseSwitchCase() { - var test, - consequent = [], - statement; - - if (matchKeyword('default')) { - lex(); - test = null; - } else { - expectKeyword('case'); - test = parseExpression(); - } - expect(':'); - - while (index < length) { - if (match('}') || matchKeyword('default') || matchKeyword('case')) { - break; - } - statement = parseStatement(); - if (typeof statement === 'undefined') { - break; - } - consequent.push(statement); - } - - return { - type: Syntax.SwitchCase, - test: test, - consequent: consequent - }; - } - - function parseSwitchStatement() { - var discriminant, cases, clause, oldInSwitch, defaultFound; - - expectKeyword('switch'); - - expect('('); - - discriminant = parseExpression(); - - expect(')'); - - expect('{'); - - cases = []; - - if (match('}')) { - lex(); - return { - type: Syntax.SwitchStatement, - discriminant: discriminant, - cases: cases - }; - } - - oldInSwitch = state.inSwitch; - state.inSwitch = true; - defaultFound = false; - - while (index < length) { - if (match('}')) { - break; - } - clause = parseSwitchCase(); - if (clause.test === null) { - if (defaultFound) { - throwError({}, Messages.MultipleDefaultsInSwitch); - } - defaultFound = true; - } - cases.push(clause); - } - - state.inSwitch = oldInSwitch; - - expect('}'); - - return { - type: Syntax.SwitchStatement, - discriminant: discriminant, - cases: cases - }; - } - - // 12.13 The throw statement - - function parseThrowStatement() { - var argument; - - expectKeyword('throw'); - - if (peekLineTerminator()) { - throwError({}, Messages.NewlineAfterThrow); - } - - argument = parseExpression(); - - consumeSemicolon(); - - return { - type: Syntax.ThrowStatement, - argument: argument - }; - } - - // 12.14 The try statement - - function parseCatchClause() { - var param; - - expectKeyword('catch'); - - expect('('); - if (match(')')) { - throwUnexpected(lookahead()); - } - - param = parseVariableIdentifier(); - // 12.14.1 - if (strict && isRestrictedWord(param.name)) { - throwErrorTolerant({}, Messages.StrictCatchVariable); - } - - expect(')'); - - return { - type: Syntax.CatchClause, - param: param, - body: parseBlock() - }; - } - - function parseTryStatement() { - var block, handlers = [], finalizer = null; - - expectKeyword('try'); - - block = parseBlock(); - - if (matchKeyword('catch')) { - handlers.push(parseCatchClause()); - } - - if (matchKeyword('finally')) { - lex(); - finalizer = parseBlock(); - } - - if (handlers.length === 0 && !finalizer) { - throwError({}, Messages.NoCatchOrFinally); - } - - return { - type: Syntax.TryStatement, - block: block, - guardedHandlers: [], - handlers: handlers, - finalizer: finalizer - }; - } - - // 12.15 The debugger statement - - function parseDebuggerStatement() { - expectKeyword('debugger'); - - consumeSemicolon(); - - return { - type: Syntax.DebuggerStatement - }; - } - - // 12 Statements - - function parseStatement() { - var token = lookahead(), - expr, - labeledBody; - - if (token.type === Token.EOF) { - throwUnexpected(token); - } - - if (token.type === Token.Punctuator) { - switch (token.value) { - case ';': - return parseEmptyStatement(); - case '{': - return parseBlock(); - case '(': - return parseExpressionStatement(); - default: - break; - } - } - - if (token.type === Token.Keyword) { - switch (token.value) { - case 'break': - return parseBreakStatement(); - case 'continue': - return parseContinueStatement(); - case 'debugger': - return parseDebuggerStatement(); - case 'do': - return parseDoWhileStatement(); - case 'for': - return parseForStatement(); - case 'function': - return parseFunctionDeclaration(); - case 'if': - return parseIfStatement(); - case 'return': - return parseReturnStatement(); - case 'switch': - return parseSwitchStatement(); - case 'throw': - return parseThrowStatement(); - case 'try': - return parseTryStatement(); - case 'var': - return parseVariableStatement(); - case 'while': - return parseWhileStatement(); - case 'with': - return parseWithStatement(); - default: - break; - } - } - - expr = parseExpression(); - - // 12.12 Labelled Statements - if ((expr.type === Syntax.Identifier) && match(':')) { - lex(); - - if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) { - throwError({}, Messages.Redeclaration, 'Label', expr.name); - } - - state.labelSet[expr.name] = true; - labeledBody = parseStatement(); - delete state.labelSet[expr.name]; - - return { - type: Syntax.LabeledStatement, - label: expr, - body: labeledBody - }; - } - - consumeSemicolon(); - - return { - type: Syntax.ExpressionStatement, - expression: expr - }; - } - - // 13 Function Definition - - function parseFunctionSourceElements() { - var sourceElement, sourceElements = [], token, directive, firstRestricted, - oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody; - - expect('{'); - - while (index < length) { - token = lookahead(); - if (token.type !== Token.StringLiteral) { - break; - } - - sourceElement = parseSourceElement(); - sourceElements.push(sourceElement); - if (sourceElement.expression.type !== Syntax.Literal) { - // this is not directive - break; - } - directive = sliceSource(token.range[0] + 1, token.range[1] - 1); - if (directive === 'use strict') { - strict = true; - if (firstRestricted) { - throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); - } - } else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - - oldLabelSet = state.labelSet; - oldInIteration = state.inIteration; - oldInSwitch = state.inSwitch; - oldInFunctionBody = state.inFunctionBody; - - state.labelSet = {}; - state.inIteration = false; - state.inSwitch = false; - state.inFunctionBody = true; - - while (index < length) { - if (match('}')) { - break; - } - sourceElement = parseSourceElement(); - if (typeof sourceElement === 'undefined') { - break; - } - sourceElements.push(sourceElement); - } - - expect('}'); - - state.labelSet = oldLabelSet; - state.inIteration = oldInIteration; - state.inSwitch = oldInSwitch; - state.inFunctionBody = oldInFunctionBody; - - return { - type: Syntax.BlockStatement, - body: sourceElements - }; - } - - function parseFunctionDeclaration() { - var id, param, params = [], body, token, stricted, firstRestricted, message, previousStrict, paramSet; - - expectKeyword('function'); - token = lookahead(); - id = parseVariableIdentifier(); - if (strict) { - if (isRestrictedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictFunctionName); - } - } else { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictFunctionName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } - } - - expect('('); - - if (!match(')')) { - paramSet = {}; - while (index < length) { - token = lookahead(); - param = parseVariableIdentifier(); - if (strict) { - if (isRestrictedWord(token.value)) { - stricted = token; - message = Messages.StrictParamName; - } - if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { - stricted = token; - message = Messages.StrictParamDupe; - } - } else if (!firstRestricted) { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictParamName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { - firstRestricted = token; - message = Messages.StrictParamDupe; - } - } - params.push(param); - paramSet[param.name] = true; - if (match(')')) { - break; - } - expect(','); - } - } - - expect(')'); - - previousStrict = strict; - body = parseFunctionSourceElements(); - if (strict && firstRestricted) { - throwError(firstRestricted, message); - } - if (strict && stricted) { - throwErrorTolerant(stricted, message); - } - strict = previousStrict; - - return { - type: Syntax.FunctionDeclaration, - id: id, - params: params, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }; - } - - function parseFunctionExpression() { - var token, id = null, stricted, firstRestricted, message, param, params = [], body, previousStrict, paramSet; - - expectKeyword('function'); - - if (!match('(')) { - token = lookahead(); - id = parseVariableIdentifier(); - if (strict) { - if (isRestrictedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictFunctionName); - } - } else { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictFunctionName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } - } - } - - expect('('); - - if (!match(')')) { - paramSet = {}; - while (index < length) { - token = lookahead(); - param = parseVariableIdentifier(); - if (strict) { - if (isRestrictedWord(token.value)) { - stricted = token; - message = Messages.StrictParamName; - } - if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { - stricted = token; - message = Messages.StrictParamDupe; - } - } else if (!firstRestricted) { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictParamName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { - firstRestricted = token; - message = Messages.StrictParamDupe; - } - } - params.push(param); - paramSet[param.name] = true; - if (match(')')) { - break; - } - expect(','); - } - } - - expect(')'); - - previousStrict = strict; - body = parseFunctionSourceElements(); - if (strict && firstRestricted) { - throwError(firstRestricted, message); - } - if (strict && stricted) { - throwErrorTolerant(stricted, message); - } - strict = previousStrict; - - return { - type: Syntax.FunctionExpression, - id: id, - params: params, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }; - } - - // 14 Program - - function parseSourceElement() { - var token = lookahead(); - - if (token.type === Token.Keyword) { - switch (token.value) { - case 'const': - case 'let': - return parseConstLetDeclaration(token.value); - case 'function': - return parseFunctionDeclaration(); - default: - return parseStatement(); - } - } - - if (token.type !== Token.EOF) { - return parseStatement(); - } - } - - function parseSourceElements() { - var sourceElement, sourceElements = [], token, directive, firstRestricted; - - while (index < length) { - token = lookahead(); - if (token.type !== Token.StringLiteral) { - break; - } - - sourceElement = parseSourceElement(); - sourceElements.push(sourceElement); - if (sourceElement.expression.type !== Syntax.Literal) { - // this is not directive - break; - } - directive = sliceSource(token.range[0] + 1, token.range[1] - 1); - if (directive === 'use strict') { - strict = true; - if (firstRestricted) { - throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); - } - } else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - - while (index < length) { - sourceElement = parseSourceElement(); - if (typeof sourceElement === 'undefined') { - break; - } - sourceElements.push(sourceElement); - } - return sourceElements; - } - - function parseProgram() { - var program; - strict = false; - program = { - type: Syntax.Program, - body: parseSourceElements() - }; - return program; - } - - // The following functions are needed only when the option to preserve - // the comments is active. - - function addComment(type, value, start, end, loc) { - assert(typeof start === 'number', 'Comment must have valid position'); - - // Because the way the actual token is scanned, often the comments - // (if any) are skipped twice during the lexical analysis. - // Thus, we need to skip adding a comment if the comment array already - // handled it. - if (extra.comments.length > 0) { - if (extra.comments[extra.comments.length - 1].range[1] > start) { - return; - } - } - - extra.comments.push({ - type: type, - value: value, - range: [start, end], - loc: loc - }); - } - - function scanComment() { - var comment, ch, loc, start, blockComment, lineComment; - - comment = ''; - blockComment = false; - lineComment = false; - - while (index < length) { - ch = source[index]; - - if (lineComment) { - ch = source[index++]; - if (isLineTerminator(ch)) { - loc.end = { - line: lineNumber, - column: index - lineStart - 1 - }; - lineComment = false; - addComment('Line', comment, start, index - 1, loc); - if (ch === '\r' && source[index] === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - comment = ''; - } else if (index >= length) { - lineComment = false; - comment += ch; - loc.end = { - line: lineNumber, - column: length - lineStart - }; - addComment('Line', comment, start, length, loc); - } else { - comment += ch; - } - } else if (blockComment) { - if (isLineTerminator(ch)) { - if (ch === '\r' && source[index + 1] === '\n') { - ++index; - comment += '\r\n'; - } else { - comment += ch; - } - ++lineNumber; - ++index; - lineStart = index; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - ch = source[index++]; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - comment += ch; - if (ch === '*') { - ch = source[index]; - if (ch === '/') { - comment = comment.substr(0, comment.length - 1); - blockComment = false; - ++index; - loc.end = { - line: lineNumber, - column: index - lineStart - }; - addComment('Block', comment, start, index, loc); - comment = ''; - } - } - } - } else if (ch === '/') { - ch = source[index + 1]; - if (ch === '/') { - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - start = index; - index += 2; - lineComment = true; - if (index >= length) { - loc.end = { - line: lineNumber, - column: index - lineStart - }; - lineComment = false; - addComment('Line', comment, start, index, loc); - } - } else if (ch === '*') { - start = index; - index += 2; - blockComment = true; - loc = { - start: { - line: lineNumber, - column: index - lineStart - 2 - } - }; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - break; - } - } else if (isWhiteSpace(ch)) { - ++index; - } else if (isLineTerminator(ch)) { - ++index; - if (ch === '\r' && source[index] === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - } else { - break; - } - } - } - - function filterCommentLocation() { - var i, entry, comment, comments = []; - - for (i = 0; i < extra.comments.length; ++i) { - entry = extra.comments[i]; - comment = { - type: entry.type, - value: entry.value - }; - if (extra.range) { - comment.range = entry.range; - } - if (extra.loc) { - comment.loc = entry.loc; - } - comments.push(comment); - } - - extra.comments = comments; - } - - function collectToken() { - var start, loc, token, range, value; - - skipComment(); - start = index; - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - - token = extra.advance(); - loc.end = { - line: lineNumber, - column: index - lineStart - }; - - if (token.type !== Token.EOF) { - range = [token.range[0], token.range[1]]; - value = sliceSource(token.range[0], token.range[1]); - extra.tokens.push({ - type: TokenName[token.type], - value: value, - range: range, - loc: loc - }); - } - - return token; - } - - function collectRegex() { - var pos, loc, regex, token; - - skipComment(); - - pos = index; - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - - regex = extra.scanRegExp(); - loc.end = { - line: lineNumber, - column: index - lineStart - }; - - // Pop the previous token, which is likely '/' or '/=' - if (extra.tokens.length > 0) { - token = extra.tokens[extra.tokens.length - 1]; - if (token.range[0] === pos && token.type === 'Punctuator') { - if (token.value === '/' || token.value === '/=') { - extra.tokens.pop(); - } - } - } - - extra.tokens.push({ - type: 'RegularExpression', - value: regex.literal, - range: [pos, index], - loc: loc - }); - - return regex; - } - - function filterTokenLocation() { - var i, entry, token, tokens = []; - - for (i = 0; i < extra.tokens.length; ++i) { - entry = extra.tokens[i]; - token = { - type: entry.type, - value: entry.value - }; - if (extra.range) { - token.range = entry.range; - } - if (extra.loc) { - token.loc = entry.loc; - } - tokens.push(token); - } - - extra.tokens = tokens; - } - - function createLiteral(token) { - return { - type: Syntax.Literal, - value: token.value - }; - } - - function createRawLiteral(token) { - return { - type: Syntax.Literal, - value: token.value, - raw: sliceSource(token.range[0], token.range[1]) - }; - } - - function createLocationMarker() { - var marker = {}; - - marker.range = [index, index]; - marker.loc = { - start: { - line: lineNumber, - column: index - lineStart - }, - end: { - line: lineNumber, - column: index - lineStart - } - }; - - marker.end = function () { - this.range[1] = index; - this.loc.end.line = lineNumber; - this.loc.end.column = index - lineStart; - }; - - marker.applyGroup = function (node) { - if (extra.range) { - node.groupRange = [this.range[0], this.range[1]]; - } - if (extra.loc) { - node.groupLoc = { - start: { - line: this.loc.start.line, - column: this.loc.start.column - }, - end: { - line: this.loc.end.line, - column: this.loc.end.column - } - }; - } - }; - - marker.apply = function (node) { - if (extra.range) { - node.range = [this.range[0], this.range[1]]; - } - if (extra.loc) { - node.loc = { - start: { - line: this.loc.start.line, - column: this.loc.start.column - }, - end: { - line: this.loc.end.line, - column: this.loc.end.column - } - }; - } - }; - - return marker; - } - - function trackGroupExpression() { - var marker, expr; - - skipComment(); - marker = createLocationMarker(); - expect('('); - - expr = parseExpression(); - - expect(')'); - - marker.end(); - marker.applyGroup(expr); - - return expr; - } - - function trackLeftHandSideExpression() { - var marker, expr; - - skipComment(); - marker = createLocationMarker(); - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[')) { - if (match('[')) { - expr = { - type: Syntax.MemberExpression, - computed: true, - object: expr, - property: parseComputedMember() - }; - marker.end(); - marker.apply(expr); - } else { - expr = { - type: Syntax.MemberExpression, - computed: false, - object: expr, - property: parseNonComputedMember() - }; - marker.end(); - marker.apply(expr); - } - } - - return expr; - } - - function trackLeftHandSideExpressionAllowCall() { - var marker, expr; - - skipComment(); - marker = createLocationMarker(); - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[') || match('(')) { - if (match('(')) { - expr = { - type: Syntax.CallExpression, - callee: expr, - 'arguments': parseArguments() - }; - marker.end(); - marker.apply(expr); - } else if (match('[')) { - expr = { - type: Syntax.MemberExpression, - computed: true, - object: expr, - property: parseComputedMember() - }; - marker.end(); - marker.apply(expr); - } else { - expr = { - type: Syntax.MemberExpression, - computed: false, - object: expr, - property: parseNonComputedMember() - }; - marker.end(); - marker.apply(expr); - } - } - - return expr; - } - - function filterGroup(node) { - var n, i, entry; - - n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {}; - for (i in node) { - if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') { - entry = node[i]; - if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) { - n[i] = entry; - } else { - n[i] = filterGroup(entry); - } - } - } - return n; - } - - function wrapTrackingFunction(range, loc) { - - return function (parseFunction) { - - function isBinary(node) { - return node.type === Syntax.LogicalExpression || - node.type === Syntax.BinaryExpression; - } - - function visit(node) { - var start, end; - - if (isBinary(node.left)) { - visit(node.left); - } - if (isBinary(node.right)) { - visit(node.right); - } - - if (range) { - if (node.left.groupRange || node.right.groupRange) { - start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0]; - end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1]; - node.range = [start, end]; - } else if (typeof node.range === 'undefined') { - start = node.left.range[0]; - end = node.right.range[1]; - node.range = [start, end]; - } - } - if (loc) { - if (node.left.groupLoc || node.right.groupLoc) { - start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start; - end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end; - node.loc = { - start: start, - end: end - }; - } else if (typeof node.loc === 'undefined') { - node.loc = { - start: node.left.loc.start, - end: node.right.loc.end - }; - } - } - } - - return function () { - var marker, node; - - skipComment(); - - marker = createLocationMarker(); - node = parseFunction.apply(null, arguments); - marker.end(); - - if (range && typeof node.range === 'undefined') { - marker.apply(node); - } - - if (loc && typeof node.loc === 'undefined') { - marker.apply(node); - } - - if (isBinary(node)) { - visit(node); - } - - return node; - }; - }; - } - - function patch() { - - var wrapTracking; - - if (extra.comments) { - extra.skipComment = skipComment; - skipComment = scanComment; - } - - if (extra.raw) { - extra.createLiteral = createLiteral; - createLiteral = createRawLiteral; - } - - if (extra.range || extra.loc) { - - extra.parseGroupExpression = parseGroupExpression; - extra.parseLeftHandSideExpression = parseLeftHandSideExpression; - extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall; - parseGroupExpression = trackGroupExpression; - parseLeftHandSideExpression = trackLeftHandSideExpression; - parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall; - - wrapTracking = wrapTrackingFunction(extra.range, extra.loc); - - extra.parseAdditiveExpression = parseAdditiveExpression; - extra.parseAssignmentExpression = parseAssignmentExpression; - extra.parseBitwiseANDExpression = parseBitwiseANDExpression; - extra.parseBitwiseORExpression = parseBitwiseORExpression; - extra.parseBitwiseXORExpression = parseBitwiseXORExpression; - extra.parseBlock = parseBlock; - extra.parseFunctionSourceElements = parseFunctionSourceElements; - extra.parseCatchClause = parseCatchClause; - extra.parseComputedMember = parseComputedMember; - extra.parseConditionalExpression = parseConditionalExpression; - extra.parseConstLetDeclaration = parseConstLetDeclaration; - extra.parseEqualityExpression = parseEqualityExpression; - extra.parseExpression = parseExpression; - extra.parseForVariableDeclaration = parseForVariableDeclaration; - extra.parseFunctionDeclaration = parseFunctionDeclaration; - extra.parseFunctionExpression = parseFunctionExpression; - extra.parseLogicalANDExpression = parseLogicalANDExpression; - extra.parseLogicalORExpression = parseLogicalORExpression; - extra.parseMultiplicativeExpression = parseMultiplicativeExpression; - extra.parseNewExpression = parseNewExpression; - extra.parseNonComputedProperty = parseNonComputedProperty; - extra.parseObjectProperty = parseObjectProperty; - extra.parseObjectPropertyKey = parseObjectPropertyKey; - extra.parsePostfixExpression = parsePostfixExpression; - extra.parsePrimaryExpression = parsePrimaryExpression; - extra.parseProgram = parseProgram; - extra.parsePropertyFunction = parsePropertyFunction; - extra.parseRelationalExpression = parseRelationalExpression; - extra.parseStatement = parseStatement; - extra.parseShiftExpression = parseShiftExpression; - extra.parseSwitchCase = parseSwitchCase; - extra.parseUnaryExpression = parseUnaryExpression; - extra.parseVariableDeclaration = parseVariableDeclaration; - extra.parseVariableIdentifier = parseVariableIdentifier; - - parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression); - parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression); - parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression); - parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression); - parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression); - parseBlock = wrapTracking(extra.parseBlock); - parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements); - parseCatchClause = wrapTracking(extra.parseCatchClause); - parseComputedMember = wrapTracking(extra.parseComputedMember); - parseConditionalExpression = wrapTracking(extra.parseConditionalExpression); - parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration); - parseEqualityExpression = wrapTracking(extra.parseEqualityExpression); - parseExpression = wrapTracking(extra.parseExpression); - parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration); - parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration); - parseFunctionExpression = wrapTracking(extra.parseFunctionExpression); - parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression); - parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression); - parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression); - parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression); - parseNewExpression = wrapTracking(extra.parseNewExpression); - parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty); - parseObjectProperty = wrapTracking(extra.parseObjectProperty); - parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey); - parsePostfixExpression = wrapTracking(extra.parsePostfixExpression); - parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression); - parseProgram = wrapTracking(extra.parseProgram); - parsePropertyFunction = wrapTracking(extra.parsePropertyFunction); - parseRelationalExpression = wrapTracking(extra.parseRelationalExpression); - parseStatement = wrapTracking(extra.parseStatement); - parseShiftExpression = wrapTracking(extra.parseShiftExpression); - parseSwitchCase = wrapTracking(extra.parseSwitchCase); - parseUnaryExpression = wrapTracking(extra.parseUnaryExpression); - parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration); - parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier); - } - - if (typeof extra.tokens !== 'undefined') { - extra.advance = advance; - extra.scanRegExp = scanRegExp; - - advance = collectToken; - scanRegExp = collectRegex; - } - } - - function unpatch() { - if (typeof extra.skipComment === 'function') { - skipComment = extra.skipComment; - } - - if (extra.raw) { - createLiteral = extra.createLiteral; - } - - if (extra.range || extra.loc) { - parseAdditiveExpression = extra.parseAdditiveExpression; - parseAssignmentExpression = extra.parseAssignmentExpression; - parseBitwiseANDExpression = extra.parseBitwiseANDExpression; - parseBitwiseORExpression = extra.parseBitwiseORExpression; - parseBitwiseXORExpression = extra.parseBitwiseXORExpression; - parseBlock = extra.parseBlock; - parseFunctionSourceElements = extra.parseFunctionSourceElements; - parseCatchClause = extra.parseCatchClause; - parseComputedMember = extra.parseComputedMember; - parseConditionalExpression = extra.parseConditionalExpression; - parseConstLetDeclaration = extra.parseConstLetDeclaration; - parseEqualityExpression = extra.parseEqualityExpression; - parseExpression = extra.parseExpression; - parseForVariableDeclaration = extra.parseForVariableDeclaration; - parseFunctionDeclaration = extra.parseFunctionDeclaration; - parseFunctionExpression = extra.parseFunctionExpression; - parseGroupExpression = extra.parseGroupExpression; - parseLeftHandSideExpression = extra.parseLeftHandSideExpression; - parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall; - parseLogicalANDExpression = extra.parseLogicalANDExpression; - parseLogicalORExpression = extra.parseLogicalORExpression; - parseMultiplicativeExpression = extra.parseMultiplicativeExpression; - parseNewExpression = extra.parseNewExpression; - parseNonComputedProperty = extra.parseNonComputedProperty; - parseObjectProperty = extra.parseObjectProperty; - parseObjectPropertyKey = extra.parseObjectPropertyKey; - parsePrimaryExpression = extra.parsePrimaryExpression; - parsePostfixExpression = extra.parsePostfixExpression; - parseProgram = extra.parseProgram; - parsePropertyFunction = extra.parsePropertyFunction; - parseRelationalExpression = extra.parseRelationalExpression; - parseStatement = extra.parseStatement; - parseShiftExpression = extra.parseShiftExpression; - parseSwitchCase = extra.parseSwitchCase; - parseUnaryExpression = extra.parseUnaryExpression; - parseVariableDeclaration = extra.parseVariableDeclaration; - parseVariableIdentifier = extra.parseVariableIdentifier; - } - - if (typeof extra.scanRegExp === 'function') { - advance = extra.advance; - scanRegExp = extra.scanRegExp; - } - } - - function stringToArray(str) { - var length = str.length, - result = [], - i; - for (i = 0; i < length; ++i) { - result[i] = str.charAt(i); - } - return result; - } - - function parse(code, options) { - var program, toString; - - toString = String; - if (typeof code !== 'string' && !(code instanceof String)) { - code = toString(code); - } - - source = code; - index = 0; - lineNumber = (source.length > 0) ? 1 : 0; - lineStart = 0; - length = source.length; - buffer = null; - state = { - allowIn: true, - labelSet: {}, - inFunctionBody: false, - inIteration: false, - inSwitch: false - }; - - extra = {}; - if (typeof options !== 'undefined') { - extra.range = (typeof options.range === 'boolean') && options.range; - extra.loc = (typeof options.loc === 'boolean') && options.loc; - extra.raw = (typeof options.raw === 'boolean') && options.raw; - if (typeof options.tokens === 'boolean' && options.tokens) { - extra.tokens = []; - } - if (typeof options.comment === 'boolean' && options.comment) { - extra.comments = []; - } - if (typeof options.tolerant === 'boolean' && options.tolerant) { - extra.errors = []; - } - } - - if (length > 0) { - if (typeof source[0] === 'undefined') { - // Try first to convert to a string. This is good as fast path - // for old IE which understands string indexing for string - // literals only and not for string object. - if (code instanceof String) { - source = code.valueOf(); - } - - // Force accessing the characters via an array. - if (typeof source[0] === 'undefined') { - source = stringToArray(code); - } - } - } - - patch(); - try { - program = parseProgram(); - if (typeof extra.comments !== 'undefined') { - filterCommentLocation(); - program.comments = extra.comments; - } - if (typeof extra.tokens !== 'undefined') { - filterTokenLocation(); - program.tokens = extra.tokens; - } - if (typeof extra.errors !== 'undefined') { - program.errors = extra.errors; - } - if (extra.range || extra.loc) { - program.body = filterGroup(program.body); - } - } catch (e) { - throw e; - } finally { - unpatch(); - extra = {}; - } - - return program; - } - - // Sync with package.json. - exports.version = '1.0.4'; - - exports.parse = parse; - - // Deep copy. - exports.Syntax = (function () { - var name, types = {}; - - if (typeof Object.create === 'function') { - types = Object.create(null); - } - - for (name in Syntax) { - if (Syntax.hasOwnProperty(name)) { - types[name] = Syntax[name]; - } - } - - if (typeof Object.freeze === 'function') { - Object.freeze(types); - } - - return types; - }()); - -})); -/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/package.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/package.json deleted file mode 100644 index 2889ca30..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "esprima", - "description": "ECMAScript parsing infrastructure for multipurpose analysis", - "homepage": "http://esprima.org", - "main": "esprima.js", - "bin": { - "esparse": "./bin/esparse.js", - "esvalidate": "./bin/esvalidate.js" - }, - "files": [ - "bin", - "test/run.js", - "test/runner.js", - "test/test.js", - "test/compat.js", - "test/reflect.js", - "esprima.js" - ], - "version": "1.0.4", - "engines": { - "node": ">=0.4.0" - }, - "maintainers": [ - { - "name": "ariya", - "email": "ariya.hidayat@gmail.com" - } - ], - "repository": { - "type": "git", - "url": "http://github.com/ariya/esprima.git" - }, - "licenses": [ - { - "type": "BSD", - "url": "http://github.com/ariya/esprima/raw/master/LICENSE.BSD" - } - ], - "keywords": [ - "ast", - "ecmascript", - "javascript", - "parser", - "syntax" - ], - "scripts": { - "test": "node test/run.js", - "benchmark": "node test/benchmarks.js", - "benchmark-quick": "node test/benchmarks.js quick" - }, - "_id": "esprima@1.0.4", - "dist": { - "shasum": "9f557e08fc3b4d26ece9dd34f8fbf476b62585ad", - "tarball": "http://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" - }, - "_npmVersion": "1.1.61", - "_npmUser": { - "name": "ariya", - "email": "ariya.hidayat@gmail.com" - }, - "directories": {}, - "_shasum": "9f557e08fc3b4d26ece9dd34f8fbf476b62585ad", - "_from": "esprima@~ 1.0.2", - "_resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", - "bugs": { - "url": "https://github.com/ariya/esprima/issues" - }, - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/compat.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/compat.js deleted file mode 100644 index ee3a6295..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/compat.js +++ /dev/null @@ -1,239 +0,0 @@ -/* - Copyright (C) 2012 Joost-Wim Boekesteijn - Copyright (C) 2011 Ariya Hidayat - - 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 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. -*/ - -/*jslint node: true */ -/*global document: true, window:true, esprima: true, testReflect: true */ - -var runTests; - -function getContext(esprima, reportCase, reportFailure) { - 'use strict'; - - var Reflect, Pattern; - - // Maps Mozilla Reflect object to our Esprima parser. - Reflect = { - parse: function (code) { - var result; - - reportCase(code); - - try { - result = esprima.parse(code); - } catch (error) { - result = error; - } - - return result; - } - }; - - // This is used by Reflect test suite to match a syntax tree. - Pattern = function (obj) { - var pattern; - - // Poor man's deep object cloning. - pattern = JSON.parse(JSON.stringify(obj)); - - // Special handling for regular expression literal since we need to - // convert it to a string literal, otherwise it will be decoded - // as object "{}" and the regular expression would be lost. - if (obj.type && obj.type === 'Literal') { - if (obj.value instanceof RegExp) { - pattern = { - type: obj.type, - value: obj.value.toString() - }; - } - } - - // Special handling for branch statement because SpiderMonkey - // prefers to put the 'alternate' property before 'consequent'. - if (obj.type && obj.type === 'IfStatement') { - pattern = { - type: pattern.type, - test: pattern.test, - consequent: pattern.consequent, - alternate: pattern.alternate - }; - } - - // Special handling for do while statement because SpiderMonkey - // prefers to put the 'test' property before 'body'. - if (obj.type && obj.type === 'DoWhileStatement') { - pattern = { - type: pattern.type, - body: pattern.body, - test: pattern.test - }; - } - - function adjustRegexLiteralAndRaw(key, value) { - if (key === 'value' && value instanceof RegExp) { - value = value.toString(); - } else if (key === 'raw' && typeof value === "string") { - // Ignore Esprima-specific 'raw' property. - return undefined; - } - return value; - } - - if (obj.type && (obj.type === 'Program')) { - pattern.assert = function (tree) { - var actual, expected; - actual = JSON.stringify(tree, adjustRegexLiteralAndRaw, 4); - expected = JSON.stringify(obj, null, 4); - - if (expected !== actual) { - reportFailure(expected, actual); - } - }; - } - - return pattern; - }; - - return { - Reflect: Reflect, - Pattern: Pattern - }; -} - -if (typeof window !== 'undefined') { - // Run all tests in a browser environment. - runTests = function () { - 'use strict'; - - var total = 0, - failures = 0; - - function setText(el, str) { - if (typeof el.innerText === 'string') { - el.innerText = str; - } else { - el.textContent = str; - } - } - - function reportCase(code) { - var report, e; - report = document.getElementById('report'); - e = document.createElement('pre'); - e.setAttribute('class', 'code'); - setText(e, code); - report.appendChild(e); - total += 1; - } - - function reportFailure(expected, actual) { - var report, e; - - failures += 1; - - report = document.getElementById('report'); - - e = document.createElement('p'); - setText(e, 'Expected'); - report.appendChild(e); - - e = document.createElement('pre'); - e.setAttribute('class', 'expected'); - setText(e, expected); - report.appendChild(e); - - e = document.createElement('p'); - setText(e, 'Actual'); - report.appendChild(e); - - e = document.createElement('pre'); - e.setAttribute('class', 'actual'); - setText(e, actual); - report.appendChild(e); - } - - setText(document.getElementById('version'), esprima.version); - - window.setTimeout(function () { - var tick, context = getContext(esprima, reportCase, reportFailure); - - tick = new Date(); - testReflect(context.Reflect, context.Pattern); - tick = (new Date()) - tick; - - if (failures > 0) { - setText(document.getElementById('status'), total + ' tests. ' + - 'Failures: ' + failures + '. ' + tick + ' ms'); - } else { - setText(document.getElementById('status'), total + ' tests. ' + - 'No failure. ' + tick + ' ms'); - } - }, 513); - }; -} else { - (function (global) { - 'use strict'; - var esprima = require('../esprima'), - tick, - total = 0, - failures = [], - header, - current, - context; - - function reportCase(code) { - total += 1; - current = code; - } - - function reportFailure(expected, actual) { - failures.push({ - source: current, - expected: expected.toString(), - actual: actual.toString() - }); - } - - context = getContext(esprima, reportCase, reportFailure); - - tick = new Date(); - require('./reflect').testReflect(context.Reflect, context.Pattern); - tick = (new Date()) - tick; - - header = total + ' tests. ' + failures.length + ' failures. ' + - tick + ' ms'; - if (failures.length) { - console.error(header); - failures.forEach(function (failure) { - console.error(failure.source + ': Expected\n ' + - failure.expected.split('\n').join('\n ') + - '\nto match\n ' + failure.actual); - }); - } else { - console.log(header); - } - process.exit(failures.length === 0 ? 0 : 1); - }(this)); -} -/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/reflect.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/reflect.js deleted file mode 100644 index dba1ba8f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/reflect.js +++ /dev/null @@ -1,422 +0,0 @@ -// This is modified from Mozilla Reflect.parse test suite (the file is located -// at js/src/tests/js1_8_5/extensions/reflect-parse.js in the source tree). -// -// Some notable changes: -// * Removed unsupported features (destructuring, let, comprehensions...). -// * Removed tests for E4X (ECMAScript for XML). -// * Removed everything related to builder. -// * Enclosed every 'Pattern' construct with a scope. -// * Tweaked some expected tree to remove generator field. -// * Removed the test for bug 632030 and bug 632024. - -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/licenses/publicdomain/ - */ - -(function (exports) { - -function testReflect(Reflect, Pattern) { - -function program(elts) { return Pattern({ type: "Program", body: elts }) } -function exprStmt(expr) { return Pattern({ type: "ExpressionStatement", expression: expr }) } -function throwStmt(expr) { return Pattern({ type: "ThrowStatement", argument: expr }) } -function returnStmt(expr) { return Pattern({ type: "ReturnStatement", argument: expr }) } -function yieldExpr(expr) { return Pattern({ type: "YieldExpression", argument: expr }) } -function lit(val) { return Pattern({ type: "Literal", value: val }) } -var thisExpr = Pattern({ type: "ThisExpression" }); -function funDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration", - id: id, - params: params, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }) } -function genFunDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration", - id: id, - params: params, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }) } -function declarator(id, init) { return Pattern({ type: "VariableDeclarator", id: id, init: init }) } -function varDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" }) } -function letDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" }) } -function constDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" }) } -function ident(name) { return Pattern({ type: "Identifier", name: name }) } -function dotExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: false, object: obj, property: id }) } -function memExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: true, object: obj, property: id }) } -function forStmt(init, test, update, body) { return Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body }) } -function forInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false }) } -function forEachInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true }) } -function breakStmt(lab) { return Pattern({ type: "BreakStatement", label: lab }) } -function continueStmt(lab) { return Pattern({ type: "ContinueStatement", label: lab }) } -function blockStmt(body) { return Pattern({ type: "BlockStatement", body: body }) } -var emptyStmt = Pattern({ type: "EmptyStatement" }); -function ifStmt(test, cons, alt) { return Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons }) } -function labStmt(lab, stmt) { return Pattern({ type: "LabeledStatement", label: lab, body: stmt }) } -function withStmt(obj, stmt) { return Pattern({ type: "WithStatement", object: obj, body: stmt }) } -function whileStmt(test, stmt) { return Pattern({ type: "WhileStatement", test: test, body: stmt }) } -function doStmt(stmt, test) { return Pattern({ type: "DoWhileStatement", test: test, body: stmt }) } -function switchStmt(disc, cases) { return Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases }) } -function caseClause(test, stmts) { return Pattern({ type: "SwitchCase", test: test, consequent: stmts }) } -function defaultClause(stmts) { return Pattern({ type: "SwitchCase", test: null, consequent: stmts }) } -function catchClause(id, guard, body) { if (guard) { return Pattern({ type: "GuardedCatchClause", param: id, guard: guard, body: body }) } else { return Pattern({ type: "CatchClause", param: id, body: body }) } } -function tryStmt(body, guarded, catches, fin) { return Pattern({ type: "TryStatement", block: body, guardedHandlers: guarded, handlers: catches, finalizer: fin }) } -function letStmt(head, body) { return Pattern({ type: "LetStatement", head: head, body: body }) } -function funExpr(id, args, body, gen) { return Pattern({ type: "FunctionExpression", - id: id, - params: args, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }) } -function genFunExpr(id, args, body) { return Pattern({ type: "FunctionExpression", - id: id, - params: args, - defaults: [], - body: body, - rest: null, - generator: false, - expression: false - }) } - -function unExpr(op, arg) { return Pattern({ type: "UnaryExpression", operator: op, argument: arg, prefix: true }) } -function binExpr(op, left, right) { return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }) } -function aExpr(op, left, right) { return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right }) } -function updExpr(op, arg, prefix) { return Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix }) } -function logExpr(op, left, right) { return Pattern({ type: "LogicalExpression", operator: op, left: left, right: right }) } - -function condExpr(test, cons, alt) { return Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt }) } -function seqExpr(exprs) { return Pattern({ type: "SequenceExpression", expressions: exprs }) } -function newExpr(callee, args) { return Pattern({ type: "NewExpression", callee: callee, arguments: args }) } -function callExpr(callee, args) { return Pattern({ type: "CallExpression", callee: callee, arguments: args }) } -function arrExpr(elts) { return Pattern({ type: "ArrayExpression", elements: elts }) } -function objExpr(elts) { return Pattern({ type: "ObjectExpression", properties: elts }) } -function objProp(key, value, kind) { return Pattern({ type: "Property", key: key, value: value, kind: kind }) } - -function arrPatt(elts) { return Pattern({ type: "ArrayPattern", elements: elts }) } -function objPatt(elts) { return Pattern({ type: "ObjectPattern", properties: elts }) } - -function localSrc(src) { return "(function(){ " + src + " })" } -function localPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([patt])))]) } -function blockSrc(src) { return "(function(){ { " + src + " } })" } -function blockPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))]) } - -function assertBlockStmt(src, patt) { - blockPatt(patt).assert(Reflect.parse(blockSrc(src))); -} - -function assertBlockExpr(src, patt) { - assertBlockStmt(src, exprStmt(patt)); -} - -function assertBlockDecl(src, patt, builder) { - blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder})); -} - -function assertLocalStmt(src, patt) { - localPatt(patt).assert(Reflect.parse(localSrc(src))); -} - -function assertLocalExpr(src, patt) { - assertLocalStmt(src, exprStmt(patt)); -} - -function assertLocalDecl(src, patt) { - localPatt(patt).assert(Reflect.parse(localSrc(src))); -} - -function assertGlobalStmt(src, patt, builder) { - program([patt]).assert(Reflect.parse(src, {builder: builder})); -} - -function assertGlobalExpr(src, patt, builder) { - program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder})); - //assertStmt(src, exprStmt(patt)); -} - -function assertGlobalDecl(src, patt) { - program([patt]).assert(Reflect.parse(src)); -} - -function assertProg(src, patt) { - program(patt).assert(Reflect.parse(src)); -} - -function assertStmt(src, patt) { - assertLocalStmt(src, patt); - assertGlobalStmt(src, patt); - assertBlockStmt(src, patt); -} - -function assertExpr(src, patt) { - assertLocalExpr(src, patt); - assertGlobalExpr(src, patt); - assertBlockExpr(src, patt); -} - -function assertDecl(src, patt) { - assertLocalDecl(src, patt); - assertGlobalDecl(src, patt); - assertBlockDecl(src, patt); -} - -function assertError(src, errorType) { - try { - Reflect.parse(src); - } catch (e) { - return; - } - throw new Error("expected " + errorType.name + " for " + uneval(src)); -} - - -// general tests - -// NB: These are useful but for now jit-test doesn't do I/O reliably. - -//program(_).assert(Reflect.parse(snarf('data/flapjax.txt'))); -//program(_).assert(Reflect.parse(snarf('data/jquery-1.4.2.txt'))); -//program(_).assert(Reflect.parse(snarf('data/prototype.js'))); -//program(_).assert(Reflect.parse(snarf('data/dojo.js.uncompressed.js'))); -//program(_).assert(Reflect.parse(snarf('data/mootools-1.2.4-core-nc.js'))); - - -// declarations - -assertDecl("var x = 1, y = 2, z = 3", - varDecl([declarator(ident("x"), lit(1)), - declarator(ident("y"), lit(2)), - declarator(ident("z"), lit(3))])); -assertDecl("var x, y, z", - varDecl([declarator(ident("x"), null), - declarator(ident("y"), null), - declarator(ident("z"), null)])); -assertDecl("function foo() { }", - funDecl(ident("foo"), [], blockStmt([]))); -assertDecl("function foo() { return 42 }", - funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))]))); - - -// Bug 591437: rebound args have their defs turned into uses -assertDecl("function f(a) { function a() { } }", - funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); -assertDecl("function f(a,b,c) { function b() { } }", - funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); - -// expressions - -assertExpr("true", lit(true)); -assertExpr("false", lit(false)); -assertExpr("42", lit(42)); -assertExpr("(/asdf/)", lit(/asdf/)); -assertExpr("this", thisExpr); -assertExpr("foo", ident("foo")); -assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar"))); -assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar"))); -assertExpr("(function(){})", funExpr(null, [], blockStmt([]))); -assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([]))); -assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([]))); -assertExpr("(++x)", updExpr("++", ident("x"), true)); -assertExpr("(x++)", updExpr("++", ident("x"), false)); -assertExpr("(+x)", unExpr("+", ident("x"))); -assertExpr("(-x)", unExpr("-", ident("x"))); -assertExpr("(!x)", unExpr("!", ident("x"))); -assertExpr("(~x)", unExpr("~", ident("x"))); -assertExpr("(delete x)", unExpr("delete", ident("x"))); -assertExpr("(typeof x)", unExpr("typeof", ident("x"))); -assertExpr("(void x)", unExpr("void", ident("x"))); -assertExpr("(x == y)", binExpr("==", ident("x"), ident("y"))); -assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y"))); -assertExpr("(x === y)", binExpr("===", ident("x"), ident("y"))); -assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y"))); -assertExpr("(x < y)", binExpr("<", ident("x"), ident("y"))); -assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y"))); -assertExpr("(x > y)", binExpr(">", ident("x"), ident("y"))); -assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y"))); -assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y"))); -assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y"))); -assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y"))); -assertExpr("(x + y)", binExpr("+", ident("x"), ident("y"))); -assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z"))); -assertExpr("(x - y)", binExpr("-", ident("x"), ident("y"))); -assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z"))); -assertExpr("(x * y)", binExpr("*", ident("x"), ident("y"))); -assertExpr("(x / y)", binExpr("/", ident("x"), ident("y"))); -assertExpr("(x % y)", binExpr("%", ident("x"), ident("y"))); -assertExpr("(x | y)", binExpr("|", ident("x"), ident("y"))); -assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y"))); -assertExpr("(x & y)", binExpr("&", ident("x"), ident("y"))); -assertExpr("(x in y)", binExpr("in", ident("x"), ident("y"))); -assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y"))); -assertExpr("(x = y)", aExpr("=", ident("x"), ident("y"))); -assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y"))); -assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y"))); -assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y"))); -assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y"))); -assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y"))); -assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y"))); -assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y"))); -assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y"))); -assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y"))); -assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y"))); -assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y"))); -assertExpr("(x || y)", logExpr("||", ident("x"), ident("y"))); -assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y"))); -assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z"))) -assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z"))); -assertExpr("(x,y)", seqExpr([ident("x"),ident("y")])) -assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")])) -assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")])); -assertExpr("(new Object)", newExpr(ident("Object"), [])); -assertExpr("(new Object())", newExpr(ident("Object"), [])); -assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)])); -assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)])); -assertExpr("(String())", callExpr(ident("String"), [])); -assertExpr("(String(42))", callExpr(ident("String"), [lit(42)])); -assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)])); -assertExpr("[]", arrExpr([])); -assertExpr("[1]", arrExpr([lit(1)])); -assertExpr("[1,2]", arrExpr([lit(1),lit(2)])); -assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)])); -assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)])); -assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)])); -assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)])); -assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)])); -assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)])); -assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined])); -assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined,undefined])); -assertExpr("[,,,,,]", arrExpr([undefined,undefined,undefined,undefined,undefined])); -assertExpr("({})", objExpr([])); -assertExpr("({x:1})", objExpr([objProp(ident("x"), lit(1), "init")])); -assertExpr("({x:1, y:2})", objExpr([objProp(ident("x"), lit(1), "init"), - objProp(ident("y"), lit(2), "init")])); -assertExpr("({x:1, y:2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"), - objProp(ident("y"), lit(2), "init"), - objProp(ident("z"), lit(3), "init") ])); -assertExpr("({x:1, 'y':2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"), - objProp(lit("y"), lit(2), "init"), - objProp(ident("z"), lit(3), "init") ])); -assertExpr("({'x':1, 'y':2, z:3})", objExpr([objProp(lit("x"), lit(1), "init"), - objProp(lit("y"), lit(2), "init"), - objProp(ident("z"), lit(3), "init") ])); -assertExpr("({'x':1, 'y':2, 3:3})", objExpr([objProp(lit("x"), lit(1), "init"), - objProp(lit("y"), lit(2), "init"), - objProp(lit(3), lit(3), "init") ])); - -// Bug 571617: eliminate constant-folding -assertExpr("2 + 3", binExpr("+", lit(2), lit(3))); - -// Bug 632026: constant-folding -assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a")))); - -// Bug 632056: constant-folding -program([exprStmt(ident("f")), - ifStmt(lit(1), - funDecl(ident("f"), [], blockStmt([])), - null)]).assert(Reflect.parse("f; if (1) function f(){}")); - -// statements - -assertStmt("throw 42", throwStmt(lit(42))); -assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null))); -assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null))); -assertStmt("for (var x; y; z) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), ident("z"), breakStmt(null))); -assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), ident("y"), ident("z"), breakStmt(null))); -assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null))); -assertStmt("for (var x; ; z) break", forStmt(varDecl([declarator(ident("x"), null)]), null, ident("z"), breakStmt(null))); -assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), null, ident("z"), breakStmt(null))); -assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null))); -assertStmt("for (var x; y; ) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), null, breakStmt(null))); -assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([declarator(ident("x"),lit(42))]), ident("y"), null, breakStmt(null))); -assertStmt("for (var x in y) break", forInStmt(varDecl([declarator(ident("x"),null)]), ident("y"), breakStmt(null))); -assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null))); -assertStmt("{ }", blockStmt([])); -assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))])); -assertStmt(";", emptyStmt); -assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null)); -assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true)))); -assertStmt("if (foo) { throw 1; throw 2; throw 3; }", - ifStmt(ident("foo"), - blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), - null)); -assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;", - ifStmt(ident("foo"), - blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), - exprStmt(lit(true)))); -assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo"))))); -assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo"))))); -assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([]))); -assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))]))); -assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([]))); -assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))]))); -assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo"))); -assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo"))); -assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }", - switchStmt(ident("foo"), - [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), - caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), - defaultClause([ exprStmt(lit(3)) ]) ])); -assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }", - switchStmt(ident("foo"), - [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), - caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), - defaultClause([ exprStmt(lit(3)) ]), - caseClause(lit(42), [ exprStmt(lit(42)) ]) ])); -assertStmt("try { } catch (e) { }", - tryStmt(blockStmt([]), - [], - [ catchClause(ident("e"), null, blockStmt([])) ], - null)); -assertStmt("try { } catch (e) { } finally { }", - tryStmt(blockStmt([]), - [], - [ catchClause(ident("e"), null, blockStmt([])) ], - blockStmt([]))); -assertStmt("try { } finally { }", - tryStmt(blockStmt([]), - [], - [], - blockStmt([]))); - -// redeclarations (TOK_NAME nodes with lexdef) - -assertStmt("function f() { function g() { } function g() { } }", - funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), - funDecl(ident("g"), [], blockStmt([]))]))); - -assertStmt("function f() { function g() { } function g() { return 42 } }", - funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), - funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); - -assertStmt("function f() { var x = 42; var x = 43; }", - funDecl(ident("f"), [], blockStmt([varDecl([declarator(ident("x"),lit(42))]), - varDecl([declarator(ident("x"),lit(43))])]))); - -// getters and setters - - assertExpr("({ get x() { return 42 } })", - objExpr([ objProp(ident("x"), - funExpr(null, [], blockStmt([returnStmt(lit(42))])), - "get" ) ])); - assertExpr("({ set x(v) { return 42 } })", - objExpr([ objProp(ident("x"), - funExpr(null, [ident("v")], blockStmt([returnStmt(lit(42))])), - "set" ) ])); - -} - -exports.testReflect = testReflect; - -}(typeof exports === 'undefined' ? this : exports)); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/run.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/run.js deleted file mode 100644 index 32ca3faa..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/run.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2012 Yusuke Suzuki - Copyright (C) 2012 Ariya Hidayat - - 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 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. -*/ - -/*jslint node:true */ - -(function () { - 'use strict'; - - var child = require('child_process'), - nodejs = '"' + process.execPath + '"', - ret = 0, - suites, - index; - - suites = [ - 'runner', - 'compat' - ]; - - function nextTest() { - var suite = suites[index]; - - if (index < suites.length) { - child.exec(nodejs + ' ./test/' + suite + '.js', function (err, stdout, stderr) { - if (stdout) { - process.stdout.write(suite + ': ' + stdout); - } - if (stderr) { - process.stderr.write(suite + ': ' + stderr); - } - if (err) { - ret = err.code; - } - index += 1; - nextTest(); - }); - } else { - process.exit(ret); - } - } - - index = 0; - nextTest(); -}()); diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/runner.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/runner.js deleted file mode 100644 index c1a3fc9b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/runner.js +++ /dev/null @@ -1,387 +0,0 @@ -/* - Copyright (C) 2012 Ariya Hidayat - Copyright (C) 2012 Joost-Wim Boekesteijn - Copyright (C) 2012 Yusuke Suzuki - Copyright (C) 2012 Arpad Borsos - Copyright (C) 2011 Ariya Hidayat - Copyright (C) 2011 Yusuke Suzuki - Copyright (C) 2011 Arpad Borsos - - 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 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. -*/ - -/*jslint browser:true node:true */ -/*global esprima:true, testFixture:true */ - -var runTests; - -// Special handling for regular expression literal since we need to -// convert it to a string literal, otherwise it will be decoded -// as object "{}" and the regular expression would be lost. -function adjustRegexLiteral(key, value) { - 'use strict'; - if (key === 'value' && value instanceof RegExp) { - value = value.toString(); - } - return value; -} - -function NotMatchingError(expected, actual) { - 'use strict'; - Error.call(this, 'Expected '); - this.expected = expected; - this.actual = actual; -} -NotMatchingError.prototype = new Error(); - -function errorToObject(e) { - 'use strict'; - var msg = e.toString(); - - // Opera 9.64 produces an non-standard string in toString(). - if (msg.substr(0, 6) !== 'Error:') { - if (typeof e.message === 'string') { - msg = 'Error: ' + e.message; - } - } - - return { - index: e.index, - lineNumber: e.lineNumber, - column: e.column, - message: msg - }; -} - -function testParse(esprima, code, syntax) { - 'use strict'; - var expected, tree, actual, options, StringObject, i, len, err; - - // alias, so that JSLint does not complain. - StringObject = String; - - options = { - comment: (typeof syntax.comments !== 'undefined'), - range: true, - loc: true, - tokens: (typeof syntax.tokens !== 'undefined'), - raw: true, - tolerant: (typeof syntax.errors !== 'undefined') - }; - - if (typeof syntax.tokens !== 'undefined') { - if (syntax.tokens.length > 0) { - options.range = (typeof syntax.tokens[0].range !== 'undefined'); - options.loc = (typeof syntax.tokens[0].loc !== 'undefined'); - } - } - - if (typeof syntax.comments !== 'undefined') { - if (syntax.comments.length > 0) { - options.range = (typeof syntax.comments[0].range !== 'undefined'); - options.loc = (typeof syntax.comments[0].loc !== 'undefined'); - } - } - - expected = JSON.stringify(syntax, null, 4); - try { - tree = esprima.parse(code, options); - tree = (options.comment || options.tokens || options.tolerant) ? tree : tree.body[0]; - - if (options.tolerant) { - for (i = 0, len = tree.errors.length; i < len; i += 1) { - tree.errors[i] = errorToObject(tree.errors[i]); - } - } - - actual = JSON.stringify(tree, adjustRegexLiteral, 4); - - // Only to ensure that there is no error when using string object. - esprima.parse(new StringObject(code), options); - - } catch (e) { - throw new NotMatchingError(expected, e.toString()); - } - if (expected !== actual) { - throw new NotMatchingError(expected, actual); - } - - function filter(key, value) { - if (key === 'value' && value instanceof RegExp) { - value = value.toString(); - } - return (key === 'loc' || key === 'range') ? undefined : value; - } - - if (options.tolerant) { - return; - } - - - // Check again without any location info. - options.range = false; - options.loc = false; - expected = JSON.stringify(syntax, filter, 4); - try { - tree = esprima.parse(code, options); - tree = (options.comment || options.tokens) ? tree : tree.body[0]; - - if (options.tolerant) { - for (i = 0, len = tree.errors.length; i < len; i += 1) { - tree.errors[i] = errorToObject(tree.errors[i]); - } - } - - actual = JSON.stringify(tree, filter, 4); - } catch (e) { - throw new NotMatchingError(expected, e.toString()); - } - if (expected !== actual) { - throw new NotMatchingError(expected, actual); - } -} - -function testError(esprima, code, exception) { - 'use strict'; - var i, options, expected, actual, handleInvalidRegexFlag; - - // Different parsing options should give the same error. - options = [ - {}, - { comment: true }, - { raw: true }, - { raw: true, comment: true } - ]; - - // If handleInvalidRegexFlag is true, an invalid flag in a regular expression - // will throw an exception. In some old version V8, this is not the case - // and hence handleInvalidRegexFlag is false. - handleInvalidRegexFlag = false; - try { - 'test'.match(new RegExp('[a-z]', 'x')); - } catch (e) { - handleInvalidRegexFlag = true; - } - - expected = JSON.stringify(exception); - - for (i = 0; i < options.length; i += 1) { - - try { - esprima.parse(code, options[i]); - } catch (e) { - actual = JSON.stringify(errorToObject(e)); - } - - if (expected !== actual) { - - // Compensate for old V8 which does not handle invalid flag. - if (exception.message.indexOf('Invalid regular expression') > 0) { - if (typeof actual === 'undefined' && !handleInvalidRegexFlag) { - return; - } - } - - throw new NotMatchingError(expected, actual); - } - - } -} - -function testAPI(esprima, code, result) { - 'use strict'; - var expected, res, actual; - - expected = JSON.stringify(result.result, null, 4); - try { - if (typeof result.property !== 'undefined') { - res = esprima[result.property]; - } else { - res = esprima[result.call].apply(esprima, result.args); - } - actual = JSON.stringify(res, adjustRegexLiteral, 4); - } catch (e) { - throw new NotMatchingError(expected, e.toString()); - } - if (expected !== actual) { - throw new NotMatchingError(expected, actual); - } -} - -function runTest(esprima, code, result) { - 'use strict'; - if (result.hasOwnProperty('lineNumber')) { - testError(esprima, code, result); - } else if (result.hasOwnProperty('result')) { - testAPI(esprima, code, result); - } else { - testParse(esprima, code, result); - } -} - -if (typeof window !== 'undefined') { - // Run all tests in a browser environment. - runTests = function () { - 'use strict'; - var total = 0, - failures = 0, - category, - fixture, - source, - tick, - expected, - index, - len; - - function setText(el, str) { - if (typeof el.innerText === 'string') { - el.innerText = str; - } else { - el.textContent = str; - } - } - - function startCategory(category) { - var report, e; - report = document.getElementById('report'); - e = document.createElement('h4'); - setText(e, category); - report.appendChild(e); - } - - function reportSuccess(code) { - var report, e; - report = document.getElementById('report'); - e = document.createElement('pre'); - e.setAttribute('class', 'code'); - setText(e, code); - report.appendChild(e); - } - - function reportFailure(code, expected, actual) { - var report, e; - - report = document.getElementById('report'); - - e = document.createElement('p'); - setText(e, 'Code:'); - report.appendChild(e); - - e = document.createElement('pre'); - e.setAttribute('class', 'code'); - setText(e, code); - report.appendChild(e); - - e = document.createElement('p'); - setText(e, 'Expected'); - report.appendChild(e); - - e = document.createElement('pre'); - e.setAttribute('class', 'expected'); - setText(e, expected); - report.appendChild(e); - - e = document.createElement('p'); - setText(e, 'Actual'); - report.appendChild(e); - - e = document.createElement('pre'); - e.setAttribute('class', 'actual'); - setText(e, actual); - report.appendChild(e); - } - - setText(document.getElementById('version'), esprima.version); - - tick = new Date(); - for (category in testFixture) { - if (testFixture.hasOwnProperty(category)) { - startCategory(category); - fixture = testFixture[category]; - for (source in fixture) { - if (fixture.hasOwnProperty(source)) { - expected = fixture[source]; - total += 1; - try { - runTest(esprima, source, expected); - reportSuccess(source, JSON.stringify(expected, null, 4)); - } catch (e) { - failures += 1; - reportFailure(source, e.expected, e.actual); - } - } - } - } - } - tick = (new Date()) - tick; - - if (failures > 0) { - setText(document.getElementById('status'), total + ' tests. ' + - 'Failures: ' + failures + '. ' + tick + ' ms'); - } else { - setText(document.getElementById('status'), total + ' tests. ' + - 'No failure. ' + tick + ' ms'); - } - }; -} else { - (function () { - 'use strict'; - - var esprima = require('../esprima'), - vm = require('vm'), - fs = require('fs'), - total = 0, - failures = [], - tick = new Date(), - expected, - header; - - vm.runInThisContext(fs.readFileSync(__dirname + '/test.js', 'utf-8')); - - Object.keys(testFixture).forEach(function (category) { - Object.keys(testFixture[category]).forEach(function (source) { - total += 1; - expected = testFixture[category][source]; - try { - runTest(esprima, source, expected); - } catch (e) { - e.source = source; - failures.push(e); - } - }); - }); - tick = (new Date()) - tick; - - header = total + ' tests. ' + failures.length + ' failures. ' + - tick + ' ms'; - if (failures.length) { - console.error(header); - failures.forEach(function (failure) { - console.error(failure.source + ': Expected\n ' + - failure.expected.split('\n').join('\n ') + - '\nto match\n ' + failure.actual); - }); - } else { - console.log(header); - } - process.exit(failures.length === 0 ? 0 : 1); - }()); -} diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/test.js b/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/test.js deleted file mode 100644 index 8ceee54b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/node_modules/esprima/test/test.js +++ /dev/null @@ -1,20238 +0,0 @@ -/* - Copyright (C) 2012 Ariya Hidayat - Copyright (C) 2012 Joost-Wim Boekesteijn - Copyright (C) 2012 Yusuke Suzuki - Copyright (C) 2012 Arpad Borsos - Copyright (C) 2011 Ariya Hidayat - Copyright (C) 2011 Yusuke Suzuki - Copyright (C) 2011 Arpad Borsos - - 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 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. -*/ - -var testFixture = { - - 'Primary Expression': { - - 'this\n': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'ThisExpression', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 0 } - } - }], - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 0 } - }, - tokens: [{ - type: 'Keyword', - value: 'this', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }] - }, - - 'null\n': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: null, - raw: 'null', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 0 } - } - }], - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 0 } - }, - tokens: [{ - type: 'Null', - value: 'null', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }] - }, - - '\n 42\n\n': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }, - range: [5, 9], - loc: { - start: { line: 2, column: 4 }, - end: { line: 4, column: 0 } - } - }], - range: [5, 9], - loc: { - start: { line: 2, column: 4 }, - end: { line: 4, column: 0 } - }, - tokens: [{ - type: 'Numeric', - value: '42', - range: [5, 7], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }] - }, - - '(1 + 2 ) * 3': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Literal', - value: 1, - raw: '1', - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'Literal', - value: 2, - raw: '2', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [1, 6], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'Literal', - value: 3, - raw: '3', - range: [11, 12], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - } - - }, - - 'Grouping Operator': { - - '(1) + (2 ) + 3': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Literal', - value: 1, - raw: '1', - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'Literal', - value: 2, - raw: '2', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - right: { - type: 'Literal', - value: 3, - raw: '3', - range: [14, 15], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - - '4 + 5 << (6)': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '<<', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Literal', - value: 4, - raw: '4', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 5, - raw: '5', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Literal', - value: 6, - raw: '6', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - } - - }, - - 'Array Initializer': { - - 'x = []': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }], - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - }, - tokens: [{ - type: 'Identifier', - value: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, { - type: 'Punctuator', - value: '=', - range: [2, 3], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Punctuator', - value: '[', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: ']', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }] - }, - - 'x = [ ]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x = [ 42 ]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [{ - type: 'Literal', - value: 42, - raw: '42', - range: [6, 8], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 8 } - } - }], - range: [4, 10], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 10 } - } - }, - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - - 'x = [ 42, ]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [{ - type: 'Literal', - value: 42, - raw: '42', - range: [6, 8], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 8 } - } - }], - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'x = [ ,, 42 ]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [ - null, - null, - { - type: 'Literal', - value: 42, - raw: '42', - range: [9, 11], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 11 } - } - }], - range: [4, 13], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - 'x = [ 1, 2, 3, ]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [{ - type: 'Literal', - value: 1, - raw: '1', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'Literal', - value: 2, - raw: '2', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, { - type: 'Literal', - value: 3, - raw: '3', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }], - range: [4, 16], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - 'x = [ 1, 2,, 3, ]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ArrayExpression', - elements: [{ - type: 'Literal', - value: 1, - raw: '1', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'Literal', - value: 2, - raw: '2', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, null, { - type: 'Literal', - value: 3, - raw: '3', - range: [13, 14], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 14 } - } - }], - range: [4, 17], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - - '日本語 = []': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: '日本語', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [6, 8], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - 'T\u203F = []': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'T\u203F', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'T\u200C = []': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'T\u200C', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'T\u200D = []': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'T\u200D', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - '\u2163\u2161 = []': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: '\u2163\u2161', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - '\u2163\u2161\u200A=\u2009[]': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: '\u2163\u2161', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - } - - }, - - 'Object Initializer': { - - 'x = {}': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [], - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x = { }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x = { answer: 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'answer', - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [14, 16], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 16 } - } - }, - kind: 'init', - range: [6, 16], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 16 } - } - }], - range: [4, 18], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 18 } - } - }, - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }, - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }, - - 'x = { if: 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'if', - range: [6, 8], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 8 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - kind: 'init', - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }], - range: [4, 14], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - 'x = { true: 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'true', - range: [6, 10], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 10 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [12, 14], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 14 } - } - }, - kind: 'init', - range: [6, 14], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 14 } - } - }], - range: [4, 16], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - 'x = { false: 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'false', - range: [6, 11], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 11 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [13, 15], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 15 } - } - }, - kind: 'init', - range: [6, 15], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 15 } - } - }], - range: [4, 17], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - - 'x = { null: 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'null', - range: [6, 10], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 10 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [12, 14], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 14 } - } - }, - kind: 'init', - range: [6, 14], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 14 } - } - }], - range: [4, 16], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - 'x = { "answer": 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Literal', - value: 'answer', - raw: '"answer"', - range: [6, 14], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 14 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [16, 18], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 18 } - } - }, - kind: 'init', - range: [6, 18], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 18 } - } - }], - range: [4, 20], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 20 } - } - }, - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - - 'x = { x: 1, x: 2 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [ - { - type: 'Property', - key: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - value: { - type: 'Literal', - value: 1, - raw: '1', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - kind: 'init', - range: [6, 10], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 10 } - } - }, - { - type: 'Property', - key: { - type: 'Identifier', - name: 'x', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }, - value: { - type: 'Literal', - value: 2, - raw: '2', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }, - kind: 'init', - range: [12, 16], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 16 } - } - } - ], - range: [4, 18], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 18 } - } - }, - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }, - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }, - - 'x = { get width() { return m_width } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'width', - range: [10, 15], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 15 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ReturnStatement', - argument: { - type: 'Identifier', - name: 'm_width', - range: [27, 34], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 34 } - } - }, - range: [20, 35], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 35 } - } - }], - range: [18, 36], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 36 } - } - }, - rest: null, - generator: false, - expression: false, - range: [18, 36], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 36 } - } - }, - kind: 'get', - range: [6, 36], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 36 } - } - }], - range: [4, 38], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 38 } - } - }, - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - }, - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - }, - - 'x = { get undef() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'undef', - range: [10, 15], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 15 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [18, 20], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 20 } - } - }, - rest: null, - generator: false, - expression: false, - range: [18, 20], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 20 } - } - }, - kind: 'get', - range: [6, 20], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 20 } - } - }], - range: [4, 22], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - - 'x = { get if() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'if', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - kind: 'get', - range: [6, 17], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 17 } - } - }], - range: [4, 19], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 19 } - } - }, - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - } - }, - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - } - }, - - 'x = { get true() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'true', - range: [10, 14], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 14 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [17, 19], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 19 } - } - }, - rest: null, - generator: false, - expression: false, - range: [17, 19], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 19 } - } - }, - kind: 'get', - range: [6, 19], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 19 } - } - }], - range: [4, 21], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - - 'x = { get false() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'false', - range: [10, 15], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 15 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [18, 20], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 20 } - } - }, - rest: null, - generator: false, - expression: false, - range: [18, 20], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 20 } - } - }, - kind: 'get', - range: [6, 20], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 20 } - } - }], - range: [4, 22], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - - 'x = { get null() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'null', - range: [10, 14], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 14 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [17, 19], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 19 } - } - }, - rest: null, - generator: false, - expression: false, - range: [17, 19], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 19 } - } - }, - kind: 'get', - range: [6, 19], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 19 } - } - }], - range: [4, 21], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - - 'x = { get "undef"() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Literal', - value: 'undef', - raw: '"undef"', - range: [10, 17], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 17 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [20, 22], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 22 } - } - }, - rest: null, - generator: false, - expression: false, - range: [20, 22], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 22 } - } - }, - kind: 'get', - range: [6, 22], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 22 } - } - }], - range: [4, 24], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 24 } - } - }, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - - 'x = { get 10() {} }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Literal', - value: 10, - raw: '10', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - kind: 'get', - range: [6, 17], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 17 } - } - }], - range: [4, 19], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 19 } - } - }, - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - } - }, - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - } - }, - - 'x = { set width(w) { m_width = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'width', - range: [10, 15], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 15 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_width', - range: [21, 28], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 28 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [31, 32], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 32 } - } - }, - range: [21, 32], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 32 } - } - }, - range: [21, 33], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 33 } - } - }], - range: [19, 34], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [19, 34], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 34 } - } - }, - kind: 'set', - range: [6, 34], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 34 } - } - }], - range: [4, 36], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - - 'x = { set if(w) { m_if = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'if', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [13, 14], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 14 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_if', - range: [18, 22], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 22 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [25, 26], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 26 } - } - }, - range: [18, 26], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 26 } - } - }, - range: [18, 27], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 27 } - } - }], - range: [16, 28], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 28 } - } - }, - rest: null, - generator: false, - expression: false, - range: [16, 28], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 28 } - } - }, - kind: 'set', - range: [6, 28], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 28 } - } - }], - range: [4, 30], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 30 } - } - }, - range: [0, 30], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 30 } - } - }, - range: [0, 30], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 30 } - } - }, - - 'x = { set true(w) { m_true = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'true', - range: [10, 14], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 14 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_true', - range: [20, 26], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 26 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [29, 30], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 30 } - } - }, - range: [20, 30], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 30 } - } - }, - range: [20, 31], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 31 } - } - }], - range: [18, 32], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 32 } - } - }, - rest: null, - generator: false, - expression: false, - range: [18, 32], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 32 } - } - }, - kind: 'set', - range: [6, 32], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 32 } - } - }], - range: [4, 34], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 34 } - } - }, - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - - 'x = { set false(w) { m_false = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'false', - range: [10, 15], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 15 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_false', - range: [21, 28], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 28 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [31, 32], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 32 } - } - }, - range: [21, 32], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 32 } - } - }, - range: [21, 33], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 33 } - } - }], - range: [19, 34], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [19, 34], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 34 } - } - }, - kind: 'set', - range: [6, 34], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 34 } - } - }], - range: [4, 36], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - - 'x = { set null(w) { m_null = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'null', - range: [10, 14], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 14 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_null', - range: [20, 26], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 26 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [29, 30], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 30 } - } - }, - range: [20, 30], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 30 } - } - }, - range: [20, 31], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 31 } - } - }], - range: [18, 32], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 32 } - } - }, - rest: null, - generator: false, - expression: false, - range: [18, 32], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 32 } - } - }, - kind: 'set', - range: [6, 32], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 32 } - } - }], - range: [4, 34], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 34 } - } - }, - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - - 'x = { set "null"(w) { m_null = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Literal', - value: 'null', - raw: '"null"', - range: [10, 16], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 16 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [17, 18], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 18 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_null', - range: [22, 28], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 28 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [31, 32], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 32 } - } - }, - range: [22, 32], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 32 } - } - }, - range: [22, 33], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 33 } - } - }], - range: [20, 34], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [20, 34], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 34 } - } - }, - kind: 'set', - range: [6, 34], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 34 } - } - }], - range: [4, 36], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - - 'x = { set 10(w) { m_null = w } }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Literal', - value: 10, - raw: '10', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'w', - range: [13, 14], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 14 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'm_null', - range: [18, 24], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 24 } - } - }, - right: { - type: 'Identifier', - name: 'w', - range: [27, 28], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 28 } - } - }, - range: [18, 28], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 28 } - } - }, - range: [18, 29], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 29 } - } - }], - range: [16, 30], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 30 } - } - }, - rest: null, - generator: false, - expression: false, - range: [16, 30], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 30 } - } - }, - kind: 'set', - range: [6, 30], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 30 } - } - }], - range: [4, 32], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 32 } - } - }, - range: [0, 32], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 32 } - } - }, - range: [0, 32], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 32 } - } - }, - - 'x = { get: 42 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'get', - range: [6, 9], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 9 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [11, 13], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 13 } - } - }, - kind: 'init', - range: [6, 13], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 13 } - } - }], - range: [4, 15], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - - 'x = { set: 43 }': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'set', - range: [6, 9], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 9 } - } - }, - value: { - type: 'Literal', - value: 43, - raw: '43', - range: [11, 13], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 13 } - } - }, - kind: 'init', - range: [6, 13], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 13 } - } - }], - range: [4, 15], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - } - - }, - - 'Comments': { - - '/* block comment */ 42': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [20, 22], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 22 } - } - }, - range: [20, 22], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 22 } - } - }, - - '42 /*The*/ /*Answer*/': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }], - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - }, - comments: [{ - type: 'Block', - value: 'The', - range: [3, 10], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 10 } - } - }, { - type: 'Block', - value: 'Answer', - range: [11, 21], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 21 } - } - }] - }, - - '42 /*the*/ /*answer*/': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [0, 2] - }, - range: [0, 21] - }], - range: [0, 21], - comments: [{ - type: 'Block', - value: 'the', - range: [3, 10] - }, { - type: 'Block', - value: 'answer', - range: [11, 21] - }] - }, - - '/* multiline\ncomment\nshould\nbe\nignored */ 42': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [42, 44], - loc: { - start: { line: 5, column: 11 }, - end: { line: 5, column: 13 } - } - }, - range: [42, 44], - loc: { - start: { line: 5, column: 11 }, - end: { line: 5, column: 13 } - } - }, - - '/*a\r\nb*/ 42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [9, 11], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }, - range: [9, 11], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }], - range: [9, 11], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - }, - comments: [{ - type: 'Block', - value: 'a\r\nb', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 3 } - } - }] - }, - - '/*a\rb*/ 42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [8, 10], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }, - range: [8, 10], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }], - range: [8, 10], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - }, - comments: [{ - type: 'Block', - value: 'a\rb', - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 3 } - } - }] - }, - - '/*a\nb*/ 42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [8, 10], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }, - range: [8, 10], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }], - range: [8, 10], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - }, - comments: [{ - type: 'Block', - value: 'a\nb', - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 3 } - } - }] - }, - - '/*a\nc*/ 42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }, - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - } - }], - loc: { - start: { line: 2, column: 4 }, - end: { line: 2, column: 6 } - }, - comments: [{ - type: 'Block', - value: 'a\nc', - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 3 } - } - }] - }, - - '// line comment\n42': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [16, 18], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }, - range: [16, 18], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }, - - '42 // line comment': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }], - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - }, - comments: [{ - type: 'Line', - value: ' line comment', - range: [3, 18], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 18 } - } - }] - }, - - '// Hello, world!\n42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [17, 19], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }, - range: [17, 19], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }], - range: [17, 19], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - }, - comments: [{ - type: 'Line', - value: ' Hello, world!', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }] - }, - - '// Hello, world!\n': { - type: 'Program', - body: [], - range: [17, 17], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 0 } - }, - comments: [{ - type: 'Line', - value: ' Hello, world!', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }] - }, - - '// Hallo, world!\n': { - type: 'Program', - body: [], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 0 } - }, - comments: [{ - type: 'Line', - value: ' Hallo, world!', - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }] - }, - - '//\n42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [3, 5], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }, - range: [3, 5], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }], - range: [3, 5], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - }, - comments: [{ - type: 'Line', - value: '', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }] - }, - - '//': { - type: 'Program', - body: [], - range: [2, 2], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 2 } - }, - comments: [{ - type: 'Line', - value: '', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }] - }, - - '// ': { - type: 'Program', - body: [], - range: [3, 3], - comments: [{ - type: 'Line', - value: ' ', - range: [0, 3] - }] - }, - - '/**/42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }], - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - }, - comments: [{ - type: 'Block', - value: '', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }] - }, - - '// Hello, world!\n\n// Another hello\n42': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [37, 39], - loc: { - start: { line: 4, column: 0 }, - end: { line: 4, column: 2 } - } - }, - range: [37, 39], - loc: { - start: { line: 4, column: 0 }, - end: { line: 4, column: 2 } - } - }], - range: [37, 39], - loc: { - start: { line: 4, column: 0 }, - end: { line: 4, column: 2 } - }, - comments: [{ - type: 'Line', - value: ' Hello, world!', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, { - type: 'Line', - value: ' Another hello', - range: [18, 36], - loc: { - start: { line: 3, column: 0 }, - end: { line: 3, column: 18 } - } - }] - }, - - 'if (x) { // Some comment\ndoThat(); }': { - type: 'Program', - body: [{ - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - consequent: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'doThat', - range: [25, 31], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }, - 'arguments': [], - range: [25, 33], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 8 } - } - }, - range: [25, 34], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 9 } - } - }], - range: [7, 36], - loc: { - start: { line: 1, column: 7 }, - end: { line: 2, column: 11 } - } - }, - alternate: null, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 11 } - } - }], - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 11 } - }, - comments: [{ - type: 'Line', - value: ' Some comment', - range: [9, 24], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 24 } - } - }] - }, - - 'switch (answer) { case 42: /* perfect */ bingo() }': { - type: 'Program', - body: [{ - type: 'SwitchStatement', - discriminant: { - type: 'Identifier', - name: 'answer', - range: [8, 14], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 14 } - } - }, - cases: [{ - type: 'SwitchCase', - test: { - type: 'Literal', - value: 42, - raw: '42', - range: [23, 25], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 25 } - } - }, - consequent: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'bingo', - range: [41, 46], - loc: { - start: { line: 1, column: 41 }, - end: { line: 1, column: 46 } - } - }, - 'arguments': [], - range: [41, 48], - loc: { - start: { line: 1, column: 41 }, - end: { line: 1, column: 48 } - } - }, - range: [41, 49], - loc: { - start: { line: 1, column: 41 }, - end: { line: 1, column: 49 } - } - }], - range: [18, 49], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 49 } - } - }], - range: [0, 50], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 50 } - } - }], - range: [0, 50], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 50 } - }, - comments: [{ - type: 'Block', - value: ' perfect ', - range: [27, 40], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 40 } - } - }] - } - - }, - - 'Numeric Literals': { - - '0': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0, - raw: '0', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - - '42': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42, - raw: '42', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - - '3': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 3, - raw: '3', - range: [0, 1] - }, - range: [0, 1] - }], - range: [0, 1], - tokens: [{ - type: 'Numeric', - value: '3', - range: [0, 1] - }] - }, - - '5': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 5, - raw: '5', - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - }, - tokens: [{ - type: 'Numeric', - value: '5', - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }] - }, - - '.14': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0.14, - raw: '.14', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - '3.14159': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 3.14159, - raw: '3.14159', - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - '6.02214179e+23': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 6.02214179e+23, - raw: '6.02214179e+23', - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - '1.492417830e-10': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 1.49241783e-10, - raw: '1.492417830e-10', - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - - '0x0': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0, - raw: '0x0', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - '0e+100': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0, - raw: '0e+100', - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - '0xabc': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0xabc, - raw: '0xabc', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - '0xdef': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0xdef, - raw: '0xdef', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - '0X1A': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0x1A, - raw: '0X1A', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - - '0x10': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0x10, - raw: '0x10', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - - '0x100': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0x100, - raw: '0x100', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - '0X04': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 0X04, - raw: '0X04', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - - '02': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 2, - raw: '02', - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - - '012': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 10, - raw: '012', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - '0012': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 10, - raw: '0012', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - } - - }, - - 'String Literals': { - - '"Hello"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello', - raw: '"Hello"', - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - '"\\n\\r\\t\\v\\b\\f\\\\\\\'\\"\\0"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: '\n\r\t\x0B\b\f\\\'"\x00', - raw: '"\\n\\r\\t\\v\\b\\f\\\\\\\'\\"\\0"', - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - - '"\\u0061"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'a', - raw: '"\\u0061"', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - '"\\x61"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'a', - raw: '"\\x61"', - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - '"\\u00"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'u00', - raw: '"\\u00"', - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - '"\\xt"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'xt', - raw: '"\\xt"', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - '"Hello\\nworld"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\nworld', - raw: '"Hello\\nworld"', - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - '"Hello\\\nworld"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Helloworld', - raw: '"Hello\\\nworld"', - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 14 } - } - }, - - '"Hello\\02World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\u0002World', - raw: '"Hello\\02World"', - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - - '"Hello\\012World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\u000AWorld', - raw: '"Hello\\012World"', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '"Hello\\122World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\122World', - raw: '"Hello\\122World"', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '"Hello\\0122World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\u000A2World', - raw: '"Hello\\0122World"', - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - - '"Hello\\312World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\u00CAWorld', - raw: '"Hello\\312World"', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '"Hello\\412World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\412World', - raw: '"Hello\\412World"', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '"Hello\\812World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello812World', - raw: '"Hello\\812World"', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '"Hello\\712World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\712World', - raw: '"Hello\\712World"', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '"Hello\\0World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\u0000World', - raw: '"Hello\\0World"', - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - '"Hello\\\r\nworld"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Helloworld', - raw: '"Hello\\\r\nworld"', - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 15 } - } - }, - - '"Hello\\1World"': { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'Hello\u0001World', - raw: '"Hello\\1World"', - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - } - }, - - 'Regular Expression Literals': { - - 'var x = /[a-z]/i': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/[a-z]/i', - raw: '/[a-z]/i', - range: [8, 16], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 16 } - } - }, - range: [4, 16], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 16 } - } - }], - kind: 'var', - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }], - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/[a-z]/i', - range: [8, 16], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 16 } - } - }] - }, - - 'var x = /[x-z]/i': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5] - }, - init: { - type: 'Literal', - value: '/[x-z]/i', - raw: '/[x-z]/i', - range: [8, 16] - }, - range: [4, 16] - }], - kind: 'var', - range: [0, 16] - }], - range: [0, 16], - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3] - }, { - type: 'Identifier', - value: 'x', - range: [4, 5] - }, { - type: 'Punctuator', - value: '=', - range: [6, 7] - }, { - type: 'RegularExpression', - value: '/[x-z]/i', - range: [8, 16] - }] - }, - - 'var x = /[a-c]/i': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/[a-c]/i', - raw: '/[a-c]/i', - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 16 } - } - }, - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 16 } - } - }], - kind: 'var', - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/[a-c]/i', - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 16 } - } - }] - }, - - 'var x = /[P QR]/i': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/[P QR]/i', - raw: '/[P QR]/i', - range: [8, 17], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 17 } - } - }, - range: [4, 17], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 17 } - } - }], - kind: 'var', - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }], - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/[P QR]/i', - range: [8, 17], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 17 } - } - }] - }, - - 'var x = /[\\]/]/': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: new RegExp('[\\]/]').toString(), - raw: '/[\\]/]/', - range: [8, 15], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 15 } - } - }, - range: [4, 15], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 15 } - } - }], - kind: 'var', - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }], - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/[\\]/]/', - range: [8, 15], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 15 } - } - }] - }, - - 'var x = /foo\\/bar/': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/foo\\/bar/', - raw: '/foo\\/bar/', - range: [8, 18], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 18 } - } - }, - range: [4, 18], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 18 } - } - }], - kind: 'var', - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }], - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/foo\\/bar/', - range: [8, 18], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 18 } - } - }] - }, - - 'var x = /=([^=\\s])+/g': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/=([^=\\s])+/g', - raw: '/=([^=\\s])+/g', - range: [8, 21], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 21 } - } - }, - range: [4, 21], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 21 } - } - }], - kind: 'var', - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }], - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/=([^=\\s])+/g', - range: [8, 21], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 21 } - } - }] - }, - - 'var x = /[P QR]/\\u0067': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/[P QR]/g', - raw: '/[P QR]/\\u0067', - range: [8, 22], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 22 } - } - }, - range: [4, 22], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 22 } - } - }], - kind: 'var', - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }], - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/[P QR]/\\u0067', - range: [8, 22], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 22 } - } - }] - }, - - 'var x = /[P QR]/\\g': { - type: 'Program', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: '/[P QR]/g', - raw: '/[P QR]/\\g', - range: [8, 18], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 18 } - } - }, - range: [4, 18], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 18 } - } - }], - kind: 'var', - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }], - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - }, - tokens: [{ - type: 'Keyword', - value: 'var', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, { - type: 'Identifier', - value: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'Punctuator', - value: '=', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, { - type: 'RegularExpression', - value: '/[P QR]/\\g', - range: [8, 18], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 18 } - } - }] - } - - }, - - 'Left-Hand-Side Expression': { - - 'new Button': { - type: 'ExpressionStatement', - expression: { - type: 'NewExpression', - callee: { - type: 'Identifier', - name: 'Button', - range: [4, 10], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 10 } - } - }, - 'arguments': [], - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - - 'new Button()': { - type: 'ExpressionStatement', - expression: { - type: 'NewExpression', - callee: { - type: 'Identifier', - name: 'Button', - range: [4, 10], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 10 } - } - }, - 'arguments': [], - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - - 'new new foo': { - type: 'ExpressionStatement', - expression: { - type: 'NewExpression', - callee: { - type: 'NewExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [8, 11], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 11 } - } - }, - 'arguments': [], - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - 'arguments': [], - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'new new foo()': { - type: 'ExpressionStatement', - expression: { - type: 'NewExpression', - callee: { - type: 'NewExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [8, 11], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 11 } - } - }, - 'arguments': [], - range: [4, 13], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 13 } - } - }, - 'arguments': [], - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - 'new foo().bar()': { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - computed: false, - object: { - type: 'NewExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - 'arguments': [], - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - property: { - type: 'Identifier', - name: 'bar', - range: [10, 13], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - 'arguments': [], - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - range: [0, 15], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 15 } - } - }, - - 'new foo[bar]': { - type: 'ExpressionStatement', - expression: { - type: 'NewExpression', - callee: { - type: 'MemberExpression', - computed: true, - object: { - type: 'Identifier', - name: 'foo', - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - property: { - type: 'Identifier', - name: 'bar', - range: [8, 11], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 11 } - } - }, - range: [4, 12], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 12 } - } - }, - 'arguments': [], - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - - 'new foo.bar()': { - type: 'ExpressionStatement', - expression: { - type: 'NewExpression', - callee: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'foo', - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - property: { - type: 'Identifier', - name: 'bar', - range: [8, 11], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 11 } - } - }, - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - 'arguments': [], - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - '( new foo).bar()': { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - computed: false, - object: { - type: 'NewExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [6, 9], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 9 } - } - }, - 'arguments': [], - range: [2, 9], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 9 } - } - }, - property: { - type: 'Identifier', - name: 'bar', - range: [11, 14], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - 'arguments': [], - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - 'foo(bar, baz)': { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'bar', - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, { - type: 'Identifier', - name: 'baz', - range: [9, 12], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 12 } - } - }], - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - '( foo )()': { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [5, 8], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 8 } - } - }, - 'arguments': [], - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - 'universe.milkyway': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'milkyway', - range: [9, 17], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - - 'universe.milkyway.solarsystem': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'milkyway', - range: [9, 17], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - property: { - type: 'Identifier', - name: 'solarsystem', - range: [18, 29], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 29 } - } - }, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - - 'universe.milkyway.solarsystem.Earth': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'MemberExpression', - computed: false, - object: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'milkyway', - range: [9, 17], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - property: { - type: 'Identifier', - name: 'solarsystem', - range: [18, 29], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 29 } - } - }, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - property: { - type: 'Identifier', - name: 'Earth', - range: [30, 35], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 35 } - } - }, - range: [0, 35], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 35 } - } - }, - range: [0, 35], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 35 } - } - }, - - 'universe[galaxyName, otherUselessName]': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: true, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'SequenceExpression', - expressions: [{ - type: 'Identifier', - name: 'galaxyName', - range: [9, 19], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 19 } - } - }, { - type: 'Identifier', - name: 'otherUselessName', - range: [21, 37], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 37 } - } - }], - range: [9, 37], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 37 } - } - }, - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - }, - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - }, - - 'universe[galaxyName]': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: true, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'galaxyName', - range: [9, 19], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 19 } - } - }, - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - - 'universe[42].galaxies': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'MemberExpression', - computed: true, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Literal', - value: 42, - raw: '42', - range: [9, 11], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - property: { - type: 'Identifier', - name: 'galaxies', - range: [13, 21], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - - 'universe(42).galaxies': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - 'arguments': [{ - type: 'Literal', - value: 42, - raw: '42', - range: [9, 11], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 11 } - } - }], - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - property: { - type: 'Identifier', - name: 'galaxies', - range: [13, 21], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - - 'universe(42).galaxies(14, 3, 77).milkyway': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - computed: false, - object: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - 'arguments': [{ - type: 'Literal', - value: 42, - raw: '42', - range: [9, 11], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 11 } - } - }], - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - property: { - type: 'Identifier', - name: 'galaxies', - range: [13, 21], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - 'arguments': [{ - type: 'Literal', - value: 14, - raw: '14', - range: [22, 24], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 24 } - } - }, { - type: 'Literal', - value: 3, - raw: '3', - range: [26, 27], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 27 } - } - }, { - type: 'Literal', - value: 77, - raw: '77', - range: [29, 31], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 31 } - } - }], - range: [0, 32], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 32 } - } - }, - property: { - type: 'Identifier', - name: 'milkyway', - range: [33, 41], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 41 } - } - }, - range: [0, 41], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 41 } - } - }, - range: [0, 41], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 41 } - } - }, - - 'earth.asia.Indonesia.prepareForElection(2014)': { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'MemberExpression', - computed: false, - object: { - type: 'MemberExpression', - computed: false, - object: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'earth', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - property: { - type: 'Identifier', - name: 'asia', - range: [6, 10], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 10 } - } - }, - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - property: { - type: 'Identifier', - name: 'Indonesia', - range: [11, 20], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 20 } - } - }, - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - property: { - type: 'Identifier', - name: 'prepareForElection', - range: [21, 39], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 39 } - } - }, - range: [0, 39], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 39 } - } - }, - 'arguments': [{ - type: 'Literal', - value: 2014, - raw: '2014', - range: [40, 44], - loc: { - start: { line: 1, column: 40 }, - end: { line: 1, column: 44 } - } - }], - range: [0, 45], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 45 } - } - }, - range: [0, 45], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 45 } - } - }, - - 'universe.if': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'if', - range: [9, 11], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'universe.true': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'true', - range: [9, 13], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - 'universe.false': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'false', - range: [9, 14], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - 'universe.null': { - type: 'ExpressionStatement', - expression: { - type: 'MemberExpression', - computed: false, - object: { - type: 'Identifier', - name: 'universe', - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - property: { - type: 'Identifier', - name: 'null', - range: [9, 13], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - } - - }, - - 'Postfix Expressions': { - - 'x++': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - prefix: false, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - 'x--': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - prefix: false, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - 'eval++': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'eval', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - prefix: false, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'eval--': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'eval', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - prefix: false, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'arguments++': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'arguments', - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - prefix: false, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'arguments--': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'arguments', - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - prefix: false, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - } - - }, - - 'Unary Operators': { - - '++x': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'x', - range: [2, 3], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 3 } - } - }, - prefix: true, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - '--x': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'x', - range: [2, 3], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 3 } - } - }, - prefix: true, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - '++eval': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'eval', - range: [2, 6], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 6 } - } - }, - prefix: true, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - '--eval': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'eval', - range: [2, 6], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 6 } - } - }, - prefix: true, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - '++arguments': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'arguments', - range: [2, 11], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 11 } - } - }, - prefix: true, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - '--arguments': { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'arguments', - range: [2, 11], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 11 } - } - }, - prefix: true, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - '+x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: '+', - argument: { - type: 'Identifier', - name: 'x', - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } - }, - prefix: true, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - - '-x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: '-', - argument: { - type: 'Identifier', - name: 'x', - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } - }, - prefix: true, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - - '~x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: '~', - argument: { - type: 'Identifier', - name: 'x', - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } - }, - prefix: true, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - - '!x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: '!', - argument: { - type: 'Identifier', - name: 'x', - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } - }, - prefix: true, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - }, - - 'void x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: 'void', - argument: { - type: 'Identifier', - name: 'x', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - prefix: true, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'delete x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: 'delete', - argument: { - type: 'Identifier', - name: 'x', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - prefix: true, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - 'typeof x': { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: 'typeof', - argument: { - type: 'Identifier', - name: 'x', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - prefix: true, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - } - - }, - - 'Multiplicative Operators': { - - 'x * y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x / y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x % y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '%', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - } - - }, - - 'Additive Operators': { - - 'x + y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x - y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - } - - }, - - 'Bitwise Shift Operator': { - - 'x << y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '<<', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x >> y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '>>', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x >>> y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '>>>', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - } - - }, - - 'Relational Operators': { - - 'x < y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x > y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '>', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x <= y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '<=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x >= y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '>=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x in y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: 'in', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x instanceof y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: 'instanceof', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [13, 14], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - 'x < y < z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - } - - }, - - 'Equality Operators': { - - 'x == y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '==', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x != y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '!=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x === y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '===', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x !== y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '!==', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - } - - }, - - 'Binary Bitwise Operators': { - - 'x & y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '&', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x ^ y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'x | y': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '|', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - } - - }, - - 'Binary Expressions': { - - 'x + y + z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x - y + z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x + y - z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x - y - z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x + y * z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x + y / z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '+', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x - y % z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '-', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'BinaryExpression', - operator: '%', - left: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x * y * z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x * y / z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '/', - left: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x * y % z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '%', - left: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x % y * z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'BinaryExpression', - operator: '%', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x << y << z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '<<', - left: { - type: 'BinaryExpression', - operator: '<<', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'x | y | z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '|', - left: { - type: 'BinaryExpression', - operator: '|', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x & y & z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '&', - left: { - type: 'BinaryExpression', - operator: '&', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x ^ y ^ z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x & y | z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '|', - left: { - type: 'BinaryExpression', - operator: '&', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x | y ^ z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '|', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x | y & z': { - type: 'ExpressionStatement', - expression: { - type: 'BinaryExpression', - operator: '|', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'BinaryExpression', - operator: '&', - left: { - type: 'Identifier', - name: 'y', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - } - - }, - - 'Binary Logical Operators': { - - 'x || y': { - type: 'ExpressionStatement', - expression: { - type: 'LogicalExpression', - operator: '||', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x && y': { - type: 'ExpressionStatement', - expression: { - type: 'LogicalExpression', - operator: '&&', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'x || y || z': { - type: 'ExpressionStatement', - expression: { - type: 'LogicalExpression', - operator: '||', - left: { - type: 'LogicalExpression', - operator: '||', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'x && y && z': { - type: 'ExpressionStatement', - expression: { - type: 'LogicalExpression', - operator: '&&', - left: { - type: 'LogicalExpression', - operator: '&&', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'x || y && z': { - type: 'ExpressionStatement', - expression: { - type: 'LogicalExpression', - operator: '||', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'LogicalExpression', - operator: '&&', - left: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - range: [5, 11], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'x || y ^ z': { - type: 'ExpressionStatement', - expression: { - type: 'LogicalExpression', - operator: '||', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'BinaryExpression', - operator: '^', - left: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'Identifier', - name: 'z', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - range: [5, 10], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 10 } - } - }, - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - } - - }, - - 'Conditional Operator': { - - 'y ? 1 : 2': { - type: 'ExpressionStatement', - expression: { - type: 'ConditionalExpression', - test: { - type: 'Identifier', - name: 'y', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - consequent: { - type: 'Literal', - value: 1, - raw: '1', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - alternate: { - type: 'Literal', - value: 2, - raw: '2', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x && y ? 1 : 2': { - type: 'ExpressionStatement', - expression: { - type: 'ConditionalExpression', - test: { - type: 'LogicalExpression', - operator: '&&', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - consequent: { - type: 'Literal', - value: 1, - raw: '1', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - alternate: { - type: 'Literal', - value: 2, - raw: '2', - range: [13, 14], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - } - - }, - - 'Assignment Operators': { - - 'x = 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'eval = 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'eval', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [7, 9], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'arguments = 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'arguments', - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [12, 14], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - 'x *= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '*=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x /= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '/=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x %= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '%=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x += 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '+=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x -= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '-=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x <<= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '<<=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [6, 8], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - 'x >>= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '>>=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [6, 8], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - 'x >>>= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '>>>=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [7, 9], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'x &= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '&=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x ^= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '^=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - 'x |= 42': { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '|=', - left: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [5, 7], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - } - - }, - - 'Block': { - - '{ foo }': { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'foo', - range: [2, 5], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 5 } - } - }, - range: [2, 6], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 6 } - } - }], - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - '{ doThis(); doThat(); }': { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'doThis', - range: [2, 8], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 8 } - } - }, - 'arguments': [], - range: [2, 10], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 10 } - } - }, - range: [2, 11], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 11 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'doThat', - range: [12, 18], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 18 } - } - }, - 'arguments': [], - range: [12, 20], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 20 } - } - }, - range: [12, 21], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 21 } - } - }], - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - } - }, - - '{}': { - type: 'BlockStatement', - body: [], - range: [0, 2], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 2 } - } - } - - }, - - 'Variable Statement': { - - 'var x': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: null, - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }], - kind: 'var', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - 'var x, y;': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: null, - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'y', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - init: null, - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }], - kind: 'var', - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'var x = 42': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [8, 10], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 10 } - } - }, - range: [4, 10], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 10 } - } - }], - kind: 'var', - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - - 'var eval = 42, arguments = 42': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'eval', - range: [4, 8], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 8 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [11, 13], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 13 } - } - }, - range: [4, 13], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'arguments', - range: [15, 24], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 24 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [27, 29], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 29 } - } - }, - range: [15, 29], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 29 } - } - }], - kind: 'var', - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - - 'var x = 14, y = 3, z = 1977': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: { - type: 'Literal', - value: 14, - raw: '14', - range: [8, 10], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 10 } - } - }, - range: [4, 10], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 10 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'y', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }, - init: { - type: 'Literal', - value: 3, - raw: '3', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }, - range: [12, 17], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 17 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'z', - range: [19, 20], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 20 } - } - }, - init: { - type: 'Literal', - value: 1977, - raw: '1977', - range: [23, 27], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 27 } - } - }, - range: [19, 27], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 27 } - } - }], - kind: 'var', - range: [0, 27], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 27 } - } - }, - - 'var implements, interface, package': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'implements', - range: [4, 14], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 14 } - } - }, - init: null, - range: [4, 14], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 14 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'interface', - range: [16, 25], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 25 } - } - }, - init: null, - range: [16, 25], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 25 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'package', - range: [27, 34], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 34 } - } - }, - init: null, - range: [27, 34], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 34 } - } - }], - kind: 'var', - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - - 'var private, protected, public, static': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'private', - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - init: null, - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'protected', - range: [13, 22], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 22 } - } - }, - init: null, - range: [13, 22], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 22 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'public', - range: [24, 30], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 30 } - } - }, - init: null, - range: [24, 30], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 30 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'static', - range: [32, 38], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 38 } - } - }, - init: null, - range: [32, 38], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 38 } - } - }], - kind: 'var', - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - } - - }, - - 'Let Statement': { - - 'let x': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: null, - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }], - kind: 'let', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - - '{ let x }': { - type: 'BlockStatement', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - init: null, - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }], - kind: 'let', - range: [2, 8], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 8 } - } - }], - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - '{ let x = 42 }': { - type: 'BlockStatement', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }], - kind: 'let', - range: [2, 13], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 13 } - } - }], - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - }, - - '{ let x = 14, y = 3, z = 1977 }': { - type: 'BlockStatement', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - init: { - type: 'Literal', - value: 14, - raw: '14', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'y', - range: [14, 15], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 15 } - } - }, - init: { - type: 'Literal', - value: 3, - raw: '3', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - range: [14, 19], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 19 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'z', - range: [21, 22], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 22 } - } - }, - init: { - type: 'Literal', - value: 1977, - raw: '1977', - range: [25, 29], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 29 } - } - }, - range: [21, 29], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 29 } - } - }], - kind: 'let', - range: [2, 30], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 30 } - } - }], - range: [0, 31], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 31 } - } - } - - }, - - 'Const Statement': { - - 'const x = 42': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }], - kind: 'const', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - - '{ const x = 42 }': { - type: 'BlockStatement', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [12, 14], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 14 } - } - }, - range: [8, 14], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 14 } - } - }], - kind: 'const', - range: [2, 15], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 15 } - } - }], - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - - '{ const x = 14, y = 3, z = 1977 }': { - type: 'BlockStatement', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - init: { - type: 'Literal', - value: 14, - raw: '14', - range: [12, 14], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 14 } - } - }, - range: [8, 14], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 14 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'y', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }, - init: { - type: 'Literal', - value: 3, - raw: '3', - range: [20, 21], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 21 } - } - }, - range: [16, 21], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 21 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'z', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }, - init: { - type: 'Literal', - value: 1977, - raw: '1977', - range: [27, 31], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 31 } - } - }, - range: [23, 31], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 31 } - } - }], - kind: 'const', - range: [2, 32], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 32 } - } - }], - range: [0, 33], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 33 } - } - } - - }, - - 'Empty Statement': { - - ';': { - type: 'EmptyStatement', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - } - - }, - - 'Expression Statement': { - - 'x': { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - - 'x, y': { - type: 'ExpressionStatement', - expression: { - type: 'SequenceExpression', - expressions: [{ - type: 'Identifier', - name: 'x', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, { - type: 'Identifier', - name: 'y', - range: [3, 4], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 4 } - } - }], - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - - '\\u0061': { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'a', - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }, - - 'a\\u0061': { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'aa', - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 7], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 7 } - } - }, - - '\\ua': { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'ua', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - - 'a\\u': { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'au', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - } - - }, - - 'If Statement': { - - 'if (morning) goodMorning()': { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'morning', - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - consequent: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'goodMorning', - range: [13, 24], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 24 } - } - }, - 'arguments': [], - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - }, - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - }, - alternate: null, - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - } - }, - - 'if (morning) (function(){})': { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'morning', - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - consequent: { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [24, 26], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 26 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 26], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 26 } - } - }, - range: [13, 27], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 27 } - } - }, - alternate: null, - range: [0, 27], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 27 } - } - }, - - 'if (morning) var x = 0;': { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'morning', - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - consequent: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [17, 18], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 18 } - } - }, - init: { - type: 'Literal', - value: 0, - raw: '0', - range: [21, 22], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 22 } - } - }, - range: [17, 22], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 22 } - } - }], - kind: 'var', - range: [13, 23], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 23 } - } - }, - alternate: null, - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - } - }, - - 'if (morning) function a(){}': { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'morning', - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - consequent: { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'a', - range: [22, 23], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 23 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [25, 27], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 27 } - } - }, - rest: null, - generator: false, - expression: false, - range: [13, 27], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 27 } - } - }, - alternate: null, - range: [0, 27], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 27 } - } - }, - - 'if (morning) goodMorning(); else goodDay()': { - type: 'IfStatement', - test: { - type: 'Identifier', - name: 'morning', - range: [4, 11], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 11 } - } - }, - consequent: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'goodMorning', - range: [13, 24], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 24 } - } - }, - 'arguments': [], - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - }, - range: [13, 27], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 27 } - } - }, - alternate: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'goodDay', - range: [33, 40], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 40 } - } - }, - 'arguments': [], - range: [33, 42], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 42 } - } - }, - range: [33, 42], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 42 } - } - }, - range: [0, 42], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 42 } - } - } - - }, - - 'Iteration Statements': { - - 'do keep(); while (true)': { - type: 'DoWhileStatement', - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'keep', - range: [3, 7], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 7 } - } - }, - 'arguments': [], - range: [3, 9], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 9 } - } - }, - range: [3, 10], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 10 } - } - }, - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [18, 22], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - } - }, - - 'do keep(); while (true);': { - type: 'DoWhileStatement', - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'keep', - range: [3, 7], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 7 } - } - }, - 'arguments': [], - range: [3, 9], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 9 } - } - }, - range: [3, 10], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 10 } - } - }, - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [18, 22], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - - 'do { x++; y--; } while (x < 10)': { - type: 'DoWhileStatement', - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'x', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - prefix: false, - range: [5, 8], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 8 } - } - }, - range: [5, 9], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 9 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'y', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - prefix: false, - range: [10, 13], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 13 } - } - }, - range: [10, 14], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 14 } - } - }], - range: [3, 16], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 16 } - } - }, - test: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - right: { - type: 'Literal', - value: 10, - raw: '10', - range: [28, 30], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 30 } - } - }, - range: [24, 30], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 30 } - } - }, - range: [0, 31], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 31 } - } - }, - - '{ do { } while (false) false }': { - type: 'BlockStatement', - body: [{ - type: 'DoWhileStatement', - body: { - type: 'BlockStatement', - body: [], - range: [5, 8], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 8 } - } - }, - test: { - type: 'Literal', - value: false, - raw: 'false', - range: [16, 21], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 21 } - } - }, - range: [2, 22], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 22 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: false, - raw: 'false', - range: [23, 28], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 28 } - } - }, - range: [23, 29], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 29 } - } - }], - range: [0, 30], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 30 } - } - }, - - 'while (true) doSomething()': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'doSomething', - range: [13, 24], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 24 } - } - }, - 'arguments': [], - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - }, - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - }, - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - } - }, - - 'while (x < 10) { x++; y--; }': { - type: 'WhileStatement', - test: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - right: { - type: 'Literal', - value: 10, - raw: '10', - range: [11, 13], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 13 } - } - }, - range: [7, 13], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 13 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'x', - range: [17, 18], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 18 } - } - }, - prefix: false, - range: [17, 20], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 20 } - } - }, - range: [17, 21], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 21 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'y', - range: [22, 23], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 23 } - } - }, - prefix: false, - range: [22, 25], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 25 } - } - }, - range: [22, 26], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 26 } - } - }], - range: [15, 28], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 28 } - } - }, - range: [0, 28], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 28 } - } - }, - - 'for(;;);': { - type: 'ForStatement', - init: null, - test: null, - update: null, - body: { - type: 'EmptyStatement', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - 'for(;;){}': { - type: 'ForStatement', - init: null, - test: null, - update: null, - body: { - type: 'BlockStatement', - body: [], - range: [7, 9], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 9 } - } - }, - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - }, - - 'for(x = 0;;);': { - type: 'ForStatement', - init: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Literal', - value: 0, - raw: '0', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - test: null, - update: null, - body: { - type: 'EmptyStatement', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - 'for(var x = 0;;);': { - type: 'ForStatement', - init: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - init: { - type: 'Literal', - value: 0, - raw: '0', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }, - range: [8, 13], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 13 } - } - }], - kind: 'var', - range: [4, 13], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 13 } - } - }, - test: null, - update: null, - body: { - type: 'EmptyStatement', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - - 'for(let x = 0;;);': { - type: 'ForStatement', - init: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - init: { - type: 'Literal', - value: 0, - raw: '0', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }, - range: [8, 13], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 13 } - } - }], - kind: 'let', - range: [4, 13], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 13 } - } - }, - test: null, - update: null, - body: { - type: 'EmptyStatement', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }, - - 'for(var x = 0, y = 1;;);': { - type: 'ForStatement', - init: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - init: { - type: 'Literal', - value: 0, - raw: '0', - range: [12, 13], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 13 } - } - }, - range: [8, 13], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'y', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }, - init: { - type: 'Literal', - value: 1, - raw: '1', - range: [19, 20], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 20 } - } - }, - range: [15, 20], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 20 } - } - }], - kind: 'var', - range: [4, 20], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 20 } - } - }, - test: null, - update: null, - body: { - type: 'EmptyStatement', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - - 'for(x = 0; x < 42;);': { - type: 'ForStatement', - init: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Literal', - value: 0, - raw: '0', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - test: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [11, 12], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 12 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - range: [11, 17], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 17 } - } - }, - update: null, - body: { - type: 'EmptyStatement', - range: [19, 20], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 20 } - } - }, - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - - 'for(x = 0; x < 42; x++);': { - type: 'ForStatement', - init: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Literal', - value: 0, - raw: '0', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - test: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [11, 12], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 12 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - range: [11, 17], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 17 } - } - }, - update: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'x', - range: [19, 20], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 20 } - } - }, - prefix: false, - range: [19, 22], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 22 } - } - }, - body: { - type: 'EmptyStatement', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - - 'for(x = 0; x < 42; x++) process(x);': { - type: 'ForStatement', - init: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Literal', - value: 0, - raw: '0', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - test: { - type: 'BinaryExpression', - operator: '<', - left: { - type: 'Identifier', - name: 'x', - range: [11, 12], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 12 } - } - }, - right: { - type: 'Literal', - value: 42, - raw: '42', - range: [15, 17], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 17 } - } - }, - range: [11, 17], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 17 } - } - }, - update: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'x', - range: [19, 20], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 20 } - } - }, - prefix: false, - range: [19, 22], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 22 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [24, 31], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 31 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [32, 33], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 33 } - } - }], - range: [24, 34], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 34 } - } - }, - range: [24, 35], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 35 } - } - }, - range: [0, 35], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 35 } - } - }, - - 'for(x in list) process(x);': { - type: 'ForInStatement', - left: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - right: { - type: 'Identifier', - name: 'list', - range: [9, 13], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 13 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [15, 22], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 22 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }], - range: [15, 25], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 25 } - } - }, - range: [15, 26], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 26 } - } - }, - each: false, - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - } - }, - - 'for (var x in list) process(x);': { - type: 'ForInStatement', - left: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - init: null, - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }], - kind: 'var', - range: [5, 10], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 10 } - } - }, - right: { - type: 'Identifier', - name: 'list', - range: [14, 18], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 18 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [20, 27], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 27 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [28, 29], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 29 } - } - }], - range: [20, 30], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 30 } - } - }, - range: [20, 31], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 31 } - } - }, - each: false, - range: [0, 31], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 31 } - } - }, - - 'for (var x = 42 in list) process(x);': { - type: 'ForInStatement', - left: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [13, 15], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 15 } - } - }, - range: [9, 15], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 15 } - } - }], - kind: 'var', - range: [5, 15], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 15 } - } - }, - right: { - type: 'Identifier', - name: 'list', - range: [19, 23], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 23 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [25, 32], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 32 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [33, 34], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 34 } - } - }], - range: [25, 35], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 35 } - } - }, - range: [25, 36], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 36 } - } - }, - each: false, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - - 'for (let x in list) process(x);': { - type: 'ForInStatement', - left: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - init: null, - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }], - kind: 'let', - range: [5, 10], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 10 } - } - }, - right: { - type: 'Identifier', - name: 'list', - range: [14, 18], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 18 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [20, 27], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 27 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [28, 29], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 29 } - } - }], - range: [20, 30], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 30 } - } - }, - range: [20, 31], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 31 } - } - }, - each: false, - range: [0, 31], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 31 } - } - }, - - 'for (let x = 42 in list) process(x);': { - type: 'ForInStatement', - left: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - init: { - type: 'Literal', - value: 42, - raw: '42', - range: [13, 15], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 15 } - } - }, - range: [9, 15], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 15 } - } - }], - kind: 'let', - range: [5, 15], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 15 } - } - }, - right: { - type: 'Identifier', - name: 'list', - range: [19, 23], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 23 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [25, 32], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 32 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [33, 34], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 34 } - } - }], - range: [25, 35], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 35 } - } - }, - range: [25, 36], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 36 } - } - }, - each: false, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - - 'for (var i = function() { return 10 in [] } in list) process(x);': { - type: 'ForInStatement', - left: { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'i', - range: [9, 10], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 10 } - } - }, - init: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ReturnStatement', - argument: { - type: 'BinaryExpression', - operator: 'in', - left: { - type: 'Literal', - value: 10, - raw: '10', - range: [33, 35], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 35 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [39, 41], - loc: { - start: { line: 1, column: 39 }, - end: { line: 1, column: 41 } - } - }, - range: [33, 41], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 41 } - } - }, - range: [26, 42], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 42 } - } - }], - range: [24, 43], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 43 } - } - }, - rest: null, - generator: false, - expression: false, - range: [13, 43], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 43 } - } - }, - range: [9, 43], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 43 } - } - }], - kind: 'var', - range: [5, 43], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 43 } - } - }, - right: { - type: 'Identifier', - name: 'list', - range: [47, 51], - loc: { - start: { line: 1, column: 47 }, - end: { line: 1, column: 51 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'process', - range: [53, 60], - loc: { - start: { line: 1, column: 53 }, - end: { line: 1, column: 60 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'x', - range: [61, 62], - loc: { - start: { line: 1, column: 61 }, - end: { line: 1, column: 62 } - } - }], - range: [53, 63], - loc: { - start: { line: 1, column: 53 }, - end: { line: 1, column: 63 } - } - }, - range: [53, 64], - loc: { - start: { line: 1, column: 53 }, - end: { line: 1, column: 64 } - } - }, - each: false, - range: [0, 64], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 64 } - } - } - - }, - - 'continue statement': { - - 'while (true) { continue; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'ContinueStatement', - label: null, - range: [15, 24], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 24 } - } - } - ], - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - }, - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - } - }, - - 'while (true) { continue }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'ContinueStatement', - label: null, - range: [15, 24], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 24 } - } - } - ], - range: [13, 25], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 25 } - } - }, - range: [0, 25], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 25 } - } - }, - - 'done: while (true) { continue done }': { - type: 'LabeledStatement', - label: { - type: 'Identifier', - name: 'done', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - body: { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [13, 17], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 17 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'ContinueStatement', - label: { - type: 'Identifier', - name: 'done', - range: [30, 34], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 34 } - } - }, - range: [21, 35], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 35 } - } - } - ], - range: [19, 36], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 36 } - } - }, - range: [6, 36], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - } - }, - - 'done: while (true) { continue done; }': { - type: 'LabeledStatement', - label: { - type: 'Identifier', - name: 'done', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - body: { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [13, 17], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 17 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'ContinueStatement', - label: { - type: 'Identifier', - name: 'done', - range: [30, 34], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 34 } - } - }, - range: [21, 35], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 35 } - } - } - ], - range: [19, 37], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 37 } - } - }, - range: [6, 37], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 37 } - } - }, - range: [0, 37], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 37 } - } - } - - }, - - 'break statement': { - - 'while (true) { break }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'BreakStatement', - label: null, - range: [15, 21], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 21 } - } - } - ], - range: [13, 22], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - - 'done: while (true) { break done }': { - type: 'LabeledStatement', - label: { - type: 'Identifier', - name: 'done', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - body: { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [13, 17], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 17 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'BreakStatement', - label: { - type: 'Identifier', - name: 'done', - range: [27, 31], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 31 } - } - }, - range: [21, 32], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 32 } - } - } - ], - range: [19, 33], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 33 } - } - }, - range: [6, 33], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 33 } - } - }, - range: [0, 33], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 33 } - } - }, - - 'done: while (true) { break done; }': { - type: 'LabeledStatement', - label: { - type: 'Identifier', - name: 'done', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - body: { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [13, 17], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 17 } - } - }, - body: { - type: 'BlockStatement', - body: [ - { - type: 'BreakStatement', - label: { - type: 'Identifier', - name: 'done', - range: [27, 31], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 31 } - } - }, - range: [21, 32], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 32 } - } - } - ], - range: [19, 34], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 34 } - } - }, - range: [6, 34], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 34 } - } - }, - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - } - - }, - - 'return statement': { - - '(function(){ return })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: null, - range: [13, 20], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 20 } - } - } - ], - range: [11, 21], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 21 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 21], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 21 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - }, - - '(function(){ return; })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: null, - range: [13, 20], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 20 } - } - } - ], - range: [11, 22], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 22 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 22], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - } - }, - - '(function(){ return x; })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: { - type: 'Identifier', - name: 'x', - range: [20, 21], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 21 } - } - }, - range: [13, 22], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 22 } - } - } - ], - range: [11, 24], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 24 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 24], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 24 } - } - }, - range: [0, 25], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 25 } - } - }, - - '(function(){ return x * y })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'x', - range: [20, 21], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 21 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - range: [20, 25], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 25 } - } - }, - range: [13, 26], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 26 } - } - } - ], - range: [11, 27], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 27 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 27], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 27 } - } - }, - range: [0, 28], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 28 } - } - } - }, - - 'with statement': { - - 'with (x) foo = bar': { - type: 'WithStatement', - object: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'foo', - range: [9, 12], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 12 } - } - }, - right: { - type: 'Identifier', - name: 'bar', - range: [15, 18], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 18 } - } - }, - range: [9, 18], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 18 } - } - }, - range: [9, 18], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 18 } - } - }, - range: [0, 18], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 18 } - } - }, - - 'with (x) foo = bar;': { - type: 'WithStatement', - object: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - body: { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'foo', - range: [9, 12], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 12 } - } - }, - right: { - type: 'Identifier', - name: 'bar', - range: [15, 18], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 18 } - } - }, - range: [9, 18], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 18 } - } - }, - range: [9, 19], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 19 } - } - }, - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - } - }, - - 'with (x) { foo = bar }': { - type: 'WithStatement', - object: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'foo', - range: [11, 14], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 14 } - } - }, - right: { - type: 'Identifier', - name: 'bar', - range: [17, 20], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 20 } - } - }, - range: [11, 20], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 20 } - } - }, - range: [11, 21], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 21 } - } - }], - range: [9, 22], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 22 } - } - }, - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - } - } - - }, - - 'switch statement': { - - 'switch (x) {}': { - type: 'SwitchStatement', - discriminant: { - type: 'Identifier', - name: 'x', - range: [8, 9], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 9 } - } - }, - cases:[], - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, - - 'switch (answer) { case 42: hi(); break; }': { - type: 'SwitchStatement', - discriminant: { - type: 'Identifier', - name: 'answer', - range: [8, 14], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 14 } - } - }, - cases: [{ - type: 'SwitchCase', - test: { - type: 'Literal', - value: 42, - raw: '42', - range: [23, 25], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 25 } - } - }, - consequent: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hi', - range: [27, 29], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 29 } - } - }, - 'arguments': [], - range: [27, 31], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 31 } - } - }, - range: [27, 32], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 32 } - } - }, { - type: 'BreakStatement', - label: null, - range: [33, 39], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 39 } - } - }], - range: [18, 39], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 39 } - } - }], - range: [0, 41], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 41 } - } - }, - - 'switch (answer) { case 42: hi(); break; default: break }': { - type: 'SwitchStatement', - discriminant: { - type: 'Identifier', - name: 'answer', - range: [8, 14], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 14 } - } - }, - cases: [{ - type: 'SwitchCase', - test: { - type: 'Literal', - value: 42, - raw: '42', - range: [23, 25], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 25 } - } - }, - consequent: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'hi', - range: [27, 29], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 29 } - } - }, - 'arguments': [], - range: [27, 31], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 31 } - } - }, - range: [27, 32], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 32 } - } - }, { - type: 'BreakStatement', - label: null, - range: [33, 39], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 39 } - } - }], - range: [18, 39], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 39 } - } - }, { - type: 'SwitchCase', - test: null, - consequent: [{ - type: 'BreakStatement', - label: null, - range: [49, 55], - loc: { - start: { line: 1, column: 49 }, - end: { line: 1, column: 55 } - } - }], - range: [40, 55], - loc: { - start: { line: 1, column: 40 }, - end: { line: 1, column: 55 } - } - }], - range: [0, 56], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 56 } - } - } - - }, - - 'Labelled Statements': { - - 'start: for (;;) break start': { - type: 'LabeledStatement', - label: { - type: 'Identifier', - name: 'start', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - body: { - type: 'ForStatement', - init: null, - test: null, - update: null, - body: { - type: 'BreakStatement', - label: { - type: 'Identifier', - name: 'start', - range: [22, 27], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 27 } - } - }, - range: [16, 27], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 27 } - } - }, - range: [7, 27], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 27 } - } - }, - range: [0, 27], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 27 } - } - }, - - 'start: while (true) break start': { - type: 'LabeledStatement', - label: { - type: 'Identifier', - name: 'start', - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - body: { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [14, 18], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 18 } - } - }, - body: { - type: 'BreakStatement', - label: { - type: 'Identifier', - name: 'start', - range: [26, 31], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 31 } - } - }, - range: [20, 31], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 31 } - } - }, - range: [7, 31], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 31 } - } - }, - range: [0, 31], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 31 } - } - } - - }, - - 'throw statement': { - - 'throw x;': { - type: 'ThrowStatement', - argument: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - range: [0, 8], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 8 } - } - }, - - 'throw x * y': { - type: 'ThrowStatement', - argument: { - type: 'BinaryExpression', - operator: '*', - left: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - right: { - type: 'Identifier', - name: 'y', - range: [10, 11], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 11 } - } - }, - range: [6, 11], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 11 } - } - }, - range: [0, 11], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 11 } - } - }, - - 'throw { message: "Error" }': { - type: 'ThrowStatement', - argument: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'message', - range: [8, 15], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 15 } - } - }, - value: { - type: 'Literal', - value: 'Error', - raw: '"Error"', - range: [17, 24], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 24 } - } - }, - kind: 'init', - range: [8, 24], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 24 } - } - }], - range: [6, 26], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 26 } - } - }, - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - } - } - - }, - - 'try statement': { - - 'try { } catch (e) { }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'e', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }, - body: { - type: 'BlockStatement', - body: [], - range: [18, 21], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 21 } - } - }, - range: [8, 21], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 21 } - } - }], - finalizer: null, - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - } - }, - - 'try { } catch (eval) { }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'eval', - range: [15, 19], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 19 } - } - }, - body: { - type: 'BlockStatement', - body: [], - range: [21, 24], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 24 } - } - }, - range: [8, 24], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 24 } - } - }], - finalizer: null, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - - 'try { } catch (arguments) { }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'arguments', - range: [15, 24], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 24 } - } - }, - body: { - type: 'BlockStatement', - body: [], - range: [26, 29], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 29 } - } - }, - range: [8, 29], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 29 } - } - }], - finalizer: null, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - - 'try { } catch (e) { say(e) }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'e', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'say', - range: [20, 23], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 23 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'e', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }], - range: [20, 26], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 26 } - } - }, - range: [20, 27], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 27 } - } - }], - range: [18, 28], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 28 } - } - }, - range: [8, 28], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 28 } - } - }], - finalizer: null, - range: [0, 28], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 28 } - } - }, - - 'try { } finally { cleanup(stuff) }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [4, 7], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 7 } - } - }, - guardedHandlers: [], - handlers: [], - finalizer: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'cleanup', - range: [18, 25], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 25 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'stuff', - range: [26, 31], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 31 } - } - }], - range: [18, 32], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 32 } - } - }, - range: [18, 33], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 33 } - } - }], - range: [16, 34], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 34 } - } - }, - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - - 'try { doThat(); } catch (e) { say(e) }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'doThat', - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }, - 'arguments': [], - range: [6, 14], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 14 } - } - }, - range: [6, 15], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 15 } - } - }], - range: [4, 17], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 17 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'e', - range: [25, 26], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 26 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'say', - range: [30, 33], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 33 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'e', - range: [34, 35], - loc: { - start: { line: 1, column: 34 }, - end: { line: 1, column: 35 } - } - }], - range: [30, 36], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 36 } - } - }, - range: [30, 37], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 37 } - } - }], - range: [28, 38], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 38 } - } - }, - range: [18, 38], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 38 } - } - }], - finalizer: null, - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - }, - - 'try { doThat(); } catch (e) { say(e) } finally { cleanup(stuff) }': { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'doThat', - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }, - 'arguments': [], - range: [6, 14], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 14 } - } - }, - range: [6, 15], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 15 } - } - }], - range: [4, 17], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 17 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'e', - range: [25, 26], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 26 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'say', - range: [30, 33], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 33 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'e', - range: [34, 35], - loc: { - start: { line: 1, column: 34 }, - end: { line: 1, column: 35 } - } - }], - range: [30, 36], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 36 } - } - }, - range: [30, 37], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 37 } - } - }], - range: [28, 38], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 38 } - } - }, - range: [18, 38], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 38 } - } - }], - finalizer: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'cleanup', - range: [49, 56], - loc: { - start: { line: 1, column: 49 }, - end: { line: 1, column: 56 } - } - }, - 'arguments': [{ - type: 'Identifier', - name: 'stuff', - range: [57, 62], - loc: { - start: { line: 1, column: 57 }, - end: { line: 1, column: 62 } - } - }], - range: [49, 63], - loc: { - start: { line: 1, column: 49 }, - end: { line: 1, column: 63 } - } - }, - range: [49, 64], - loc: { - start: { line: 1, column: 49 }, - end: { line: 1, column: 64 } - } - }], - range: [47, 65], - loc: { - start: { line: 1, column: 47 }, - end: { line: 1, column: 65 } - } - }, - range: [0, 65], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 65 } - } - } - - }, - - 'debugger statement': { - - 'debugger;': { - type: 'DebuggerStatement', - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 9 } - } - } - - }, - - 'Function Definition': { - - 'function hello() { sayHi(); }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'hello', - range: [9, 14], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 14 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'sayHi', - range: [19, 24], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 24 } - } - }, - 'arguments': [], - range: [19, 26], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 26 } - } - }, - range: [19, 27], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 27 } - } - }], - range: [17, 29], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 29 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - - 'function eval() { }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'eval', - range: [9, 13], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 13 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [16, 19], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 19 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - } - }, - - 'function arguments() { }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'arguments', - range: [9, 18], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 18 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [21, 24], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 24 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - } - }, - - 'function test(t, t) { }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'test', - range: [9, 13], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 13 } - } - }, - params: [{ - type: 'Identifier', - name: 't', - range: [14, 15], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 15 } - } - }, { - type: 'Identifier', - name: 't', - range: [17, 18], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 18 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [20, 23], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 23 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - } - }, - - '(function test(t, t) { })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'test', - range: [10, 14], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 14 } - } - }, - params: [{ - type: 'Identifier', - name: 't', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }, { - type: 'Identifier', - name: 't', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [21, 24], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 24 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 24], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 24 } - } - }, - range: [0, 25], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 25 } - } - }, - - 'function eval() { function inner() { "use strict" } }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'eval', - range: [9, 13], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 13 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'inner', - range: [27, 32], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 32 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '\"use strict\"', - range: [37, 49], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 49 } - } - }, - range: [37, 50], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 50 } - } - }], - range: [35, 51], - loc: { - start: { line: 1, column: 35 }, - end: { line: 1, column: 51 } - } - }, - rest: null, - generator: false, - expression: false, - range: [18, 51], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 51 } - } - }], - range: [16, 53], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 53 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 53], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 53 } - } - }, - - 'function hello(a) { sayHi(); }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'hello', - range: [9, 14], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 14 } - } - }, - params: [{ - type: 'Identifier', - name: 'a', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'sayHi', - range: [20, 25], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 25 } - } - }, - 'arguments': [], - range: [20, 27], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 27 } - } - }, - range: [20, 28], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 28 } - } - }], - range: [18, 30], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 30 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 30], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 30 } - } - }, - - 'function hello(a, b) { sayHi(); }': { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'hello', - range: [9, 14], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 14 } - } - }, - params: [{ - type: 'Identifier', - name: 'a', - range: [15, 16], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 16 } - } - }, { - type: 'Identifier', - name: 'b', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'sayHi', - range: [23, 28], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 28 } - } - }, - 'arguments': [], - range: [23, 30], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 30 } - } - }, - range: [23, 31], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 31 } - } - }], - range: [21, 33], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 33 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 33], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 33 } - } - }, - - 'var hi = function() { sayHi() };': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'hi', - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - init: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'sayHi', - range: [22, 27], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 27 } - } - }, - 'arguments': [], - range: [22, 29], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 29 } - } - }, - range: [22, 30], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 30 } - } - }], - range: [20, 31], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 31 } - } - }, - rest: null, - generator: false, - expression: false, - range: [9, 31], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 31 } - } - }, - range: [4, 31], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 31 } - } - }], - kind: 'var', - range: [0, 32], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 32 } - } - }, - - 'var hi = function eval() { };': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'hi', - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - init: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'eval', - range: [18, 22], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 22 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [25, 28], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 28 } - } - }, - rest: null, - generator: false, - expression: false, - range: [9, 28], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 28 } - } - }, - range: [4, 28], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 28 } - } - }], - kind: 'var', - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } - }, - - 'var hi = function arguments() { };': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'hi', - range: [4, 6], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 6 } - } - }, - init: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'arguments', - range: [18, 27], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 27 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [30, 33], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 33 } - } - }, - rest: null, - generator: false, - expression: false, - range: [9, 33], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 33 } - } - }, - range: [4, 33], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 33 } - } - }], - kind: 'var', - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - } - }, - - 'var hello = function hi() { sayHi() };': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'hello', - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }, - init: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'hi', - range: [21, 23], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 23 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'sayHi', - range: [28, 33], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 33 } - } - }, - 'arguments': [], - range: [28, 35], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 35 } - } - }, - range: [28, 36], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 36 } - } - }], - range: [26, 37], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 37 } - } - }, - rest: null, - generator: false, - expression: false, - range: [12, 37], - loc: { - start: { line: 1, column: 12 }, - end: { line: 1, column: 37 } - } - }, - range: [4, 37], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 37 } - } - }], - kind: 'var', - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - } - }, - - '(function(){})': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [11, 13], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 13 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 13], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 13 } - } - }, - range: [0, 14], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 14 } - } - } - - }, - - 'Automatic semicolon insertion': { - - '{ x\n++y }': { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'x', - range: [2, 3], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 3 } - } - }, - range: [2, 4], - loc: { - start: { line: 1, column: 2 }, - end: { line: 2, column: 0 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'y', - range: [6, 7], - loc: { - start: { line: 2, column: 2 }, - end: { line: 2, column: 3 } - } - }, - prefix: true, - range: [4, 7], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 3 } - } - }, - range: [4, 8], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 4 } - } - }], - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 5 } - } - }, - - '{ x\n--y }': { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'x', - range: [2, 3], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 3 } - } - }, - range: [2, 4], - loc: { - start: { line: 1, column: 2 }, - end: { line: 2, column: 0 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'y', - range: [6, 7], - loc: { - start: { line: 2, column: 2 }, - end: { line: 2, column: 3 } - } - }, - prefix: true, - range: [4, 7], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 3 } - } - }, - range: [4, 8], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 4 } - } - }], - range: [0, 9], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 5 } - } - }, - - 'var x /* comment */;': { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - init: null, - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }], - kind: 'var', - range: [0, 20], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 20 } - } - }, - - '{ var x = 14, y = 3\nz; }': { - type: 'BlockStatement', - body: [{ - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [6, 7], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 7 } - } - }, - init: { - type: 'Literal', - value: 14, - raw: '14', - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - range: [6, 12], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 12 } - } - }, { - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'y', - range: [14, 15], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 15 } - } - }, - init: { - type: 'Literal', - value: 3, - raw: '3', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - range: [14, 19], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 19 } - } - }], - kind: 'var', - range: [2, 20], - loc: { - start: { line: 1, column: 2 }, - end: { line: 2, column: 0 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'z', - range: [20, 21], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 1 } - } - }, - range: [20, 22], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - }], - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 4 } - } - }, - - 'while (true) { continue\nthere; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ContinueStatement', - label: null, - range: [15, 23], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 23 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'there', - range: [24, 29], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 5 } - } - }, - range: [24, 30], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }], - range: [13, 32], - loc: { - start: { line: 1, column: 13 }, - end: { line: 2, column: 8 } - } - }, - range: [0, 32], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 8 } - } - }, - - 'while (true) { continue // Comment\nthere; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ContinueStatement', - label: null, - range: [15, 23], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 23 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'there', - range: [35, 40], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 5 } - } - }, - range: [35, 41], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }], - range: [13, 43], - loc: { - start: { line: 1, column: 13 }, - end: { line: 2, column: 8 } - } - }, - range: [0, 43], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 8 } - } - }, - - 'while (true) { continue /* Multiline\nComment */there; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'ContinueStatement', - label: null, - range: [15, 23], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 23 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'there', - range: [47, 52], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 15 } - } - }, - range: [47, 53], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 16 } - } - }], - range: [13, 55], - loc: { - start: { line: 1, column: 13 }, - end: { line: 2, column: 18 } - } - }, - range: [0, 55], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 18 } - } - }, - - 'while (true) { break\nthere; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'BreakStatement', - label: null, - range: [15, 20], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 20 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'there', - range: [21, 26], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 5 } - } - }, - range: [21, 27], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }], - range: [13, 29], - loc: { - start: { line: 1, column: 13 }, - end: { line: 2, column: 8 } - } - }, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 8 } - } - }, - - 'while (true) { break // Comment\nthere; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'BreakStatement', - label: null, - range: [15, 20], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 20 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'there', - range: [32, 37], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 5 } - } - }, - range: [32, 38], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }], - range: [13, 40], - loc: { - start: { line: 1, column: 13 }, - end: { line: 2, column: 8 } - } - }, - range: [0, 40], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 8 } - } - }, - - 'while (true) { break /* Multiline\nComment */there; }': { - type: 'WhileStatement', - test: { - type: 'Literal', - value: true, - raw: 'true', - range: [7, 11], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 11 } - } - }, - body: { - type: 'BlockStatement', - body: [{ - type: 'BreakStatement', - label: null, - range: [15, 20], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 20 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'there', - range: [44, 49], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 15 } - } - }, - range: [44, 50], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 16 } - } - }], - range: [13, 52], - loc: { - start: { line: 1, column: 13 }, - end: { line: 2, column: 18 } - } - }, - range: [0, 52], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 18 } - } - }, - - '(function(){ return\nx; })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: null, - range: [13, 19], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 19 } - } - }, - { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'x', - range: [20, 21], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 1 } - } - }, - range: [20, 22], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - } - ], - range: [11, 24], - loc: { - start: { line: 1, column: 11 }, - end: { line: 2, column: 4 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 24], - loc: { - start: { line: 1, column: 1 }, - end: { line: 2, column: 4 } - } - }, - range: [0, 25], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 5 } - } - }, - - '(function(){ return // Comment\nx; })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: null, - range: [13, 19], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 19 } - } - }, - { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'x', - range: [31, 32], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 1 } - } - }, - range: [31, 33], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 2 } - } - } - ], - range: [11, 35], - loc: { - start: { line: 1, column: 11 }, - end: { line: 2, column: 4 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 35], - loc: { - start: { line: 1, column: 1 }, - end: { line: 2, column: 4 } - } - }, - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 5 } - } - }, - - '(function(){ return/* Multiline\nComment */x; })': { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [ - { - type: 'ReturnStatement', - argument: null, - range: [13, 19], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 19 } - } - }, - { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'x', - range: [42, 43], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 11 } - } - }, - range: [42, 44], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 12 } - } - } - ], - range: [11, 46], - loc: { - start: { line: 1, column: 11 }, - end: { line: 2, column: 14 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 46], - loc: { - start: { line: 1, column: 1 }, - end: { line: 2, column: 14 } - } - }, - range: [0, 47], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 15 } - } - }, - - '{ throw error\nerror; }': { - type: 'BlockStatement', - body: [{ - type: 'ThrowStatement', - argument: { - type: 'Identifier', - name: 'error', - range: [8, 13], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 13 } - } - }, - range: [2, 14], - loc: { - start: { line: 1, column: 2 }, - end: { line: 2, column: 0 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'error', - range: [14, 19], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 5 } - } - }, - range: [14, 20], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }], - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 8 } - } - }, - - '{ throw error// Comment\nerror; }': { - type: 'BlockStatement', - body: [{ - type: 'ThrowStatement', - argument: { - type: 'Identifier', - name: 'error', - range: [8, 13], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 13 } - } - }, - range: [2, 24], - loc: { - start: { line: 1, column: 2 }, - end: { line: 2, column: 0 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'error', - range: [24, 29], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 5 } - } - }, - range: [24, 30], - loc: { - start: { line: 2, column: 0 }, - end: { line: 2, column: 6 } - } - }], - range: [0, 32], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 8 } - } - }, - - '{ throw error/* Multiline\nComment */error; }': { - type: 'BlockStatement', - body: [{ - type: 'ThrowStatement', - argument: { - type: 'Identifier', - name: 'error', - range: [8, 13], - loc: { - start: { line: 1, column: 8 }, - end: { line: 1, column: 13 } - } - }, - range: [2, 36], - loc: { - start: { line: 1, column: 2 }, - end: { line: 2, column: 10 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'error', - range: [36, 41], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 15 } - } - }, - range: [36, 42], - loc: { - start: { line: 2, column: 10 }, - end: { line: 2, column: 16 } - } - }], - range: [0, 44], - loc: { - start: { line: 1, column: 0 }, - end: { line: 2, column: 18 } - } - } - - }, - - 'Source elements': { - - '': { - type: 'Program', - body: [], - range: [0, 0], - loc: { - start: { line: 0, column: 0 }, - end: { line: 0, column: 0 } - }, - tokens: [] - } - }, - - 'Invalid syntax': { - - '{': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected end of input' - }, - - '}': { - index: 0, - lineNumber: 1, - column: 1, - message: 'Error: Line 1: Unexpected token }' - }, - - '3ea': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3in []': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3e': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3e+': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3e-': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3x': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3x0': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '0x': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '09': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '018': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '01a': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '3in[]': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '0x3in[]': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '"Hello\nWorld"': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'x\\': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'x\\u005c': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'x\\u002a': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'var x = /(s/g': { - index: 13, - lineNumber: 1, - column: 14, - message: 'Error: Line 1: Invalid regular expression' - }, - - '/': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Invalid regular expression: missing /' - }, - - '/test': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Invalid regular expression: missing /' - }, - - 'var x = /[a-z]/\\ux': { - index: 18, - lineNumber: 1, - column: 19, - message: 'Error: Line 1: Invalid regular expression' - }, - - '3 = 4': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - 'func() = 4': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '(1 + 1) = 10': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '1++': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '1--': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '++1': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '--1': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - 'for((1 + 1) in list) process(x);': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Invalid left-hand side in for-in' - }, - - '[': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected end of input' - }, - - '[,': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected end of input' - }, - - '1 + {': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Unexpected end of input' - }, - - '1 + { t:t ': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Unexpected end of input' - }, - - '1 + { t:t,': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'var x = /\n/': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Invalid regular expression: missing /' - }, - - 'var x = "\n': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'var if = 42': { - index: 4, - lineNumber: 1, - column: 5, - message: 'Error: Line 1: Unexpected token if' - }, - - 'i + 2 = 42': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '+i = 42': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }, - - '1 + (': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Unexpected end of input' - }, - - '\n\n\n{': { - index: 4, - lineNumber: 4, - column: 2, - message: 'Error: Line 4: Unexpected end of input' - }, - - '\n/* Some multiline\ncomment */\n)': { - index: 30, - lineNumber: 4, - column: 1, - message: 'Error: Line 4: Unexpected token )' - }, - - '{ set 1 }': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Unexpected number' - }, - - '{ get 2 }': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Unexpected number' - }, - - '({ set: s(if) { } })': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Unexpected token if' - }, - - '({ set s(.) { } })': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token .' - }, - - '({ set s() { } })': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token )' - }, - - '({ set: s() { } })': { - index: 12, - lineNumber: 1, - column: 13, - message: 'Error: Line 1: Unexpected token {' - }, - - '({ set: s(a, b) { } })': { - index: 16, - lineNumber: 1, - column: 17, - message: 'Error: Line 1: Unexpected token {' - }, - - '({ get: g(d) { } })': { - index: 13, - lineNumber: 1, - column: 14, - message: 'Error: Line 1: Unexpected token {' - }, - - '({ get i() { }, i: 42 })': { - index: 21, - lineNumber: 1, - column: 22, - message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' - }, - - '({ i: 42, get i() { } })': { - index: 21, - lineNumber: 1, - column: 22, - message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' - }, - - '({ set i(x) { }, i: 42 })': { - index: 22, - lineNumber: 1, - column: 23, - message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' - }, - - '({ i: 42, set i(x) { } })': { - index: 22, - lineNumber: 1, - column: 23, - message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' - }, - - '({ get i() { }, get i() { } })': { - index: 27, - lineNumber: 1, - column: 28, - message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' - }, - - '({ set i(x) { }, set i(x) { } })': { - index: 29, - lineNumber: 1, - column: 30, - message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' - }, - - 'function t(if) { }': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Unexpected token if' - }, - - 'function t(true) { }': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Unexpected token true' - }, - - 'function t(false) { }': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Unexpected token false' - }, - - 'function t(null) { }': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Unexpected token null' - }, - - 'function null() { }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token null' - }, - - 'function true() { }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token true' - }, - - 'function false() { }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token false' - }, - - 'function if() { }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token if' - }, - - 'a b;': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected identifier' - }, - - 'if.a;': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token .' - }, - - 'a if;': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token if' - }, - - 'a class;': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected reserved word' - }, - - 'break\n': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Illegal break statement' - }, - - 'break 1;': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Unexpected number' - }, - - 'continue\n': { - index: 8, - lineNumber: 1, - column: 9, - message: 'Error: Line 1: Illegal continue statement' - }, - - 'continue 2;': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected number' - }, - - 'throw': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'throw;': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Unexpected token ;' - }, - - 'throw\n': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Illegal newline after throw' - }, - - 'for (var i, i2 in {});': { - index: 15, - lineNumber: 1, - column: 16, - message: 'Error: Line 1: Unexpected token in' - }, - - 'for ((i in {}));': { - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Unexpected token )' - }, - - 'for (i + 1 in {});': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Invalid left-hand side in for-in' - }, - - 'for (+i in {});': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Invalid left-hand side in for-in' - }, - - 'if(false)': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'if(false) doThis(); else': { - index: 24, - lineNumber: 1, - column: 25, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'do': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'while(false)': { - index: 12, - lineNumber: 1, - column: 13, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'for(;;)': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'with(x)': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'try { }': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Missing catch or finally after try' - }, - - 'try {} catch (42) {} ': { - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Unexpected number' - }, - - 'try {} catch (answer()) {} ': { - index: 20, - lineNumber: 1, - column: 21, - message: 'Error: Line 1: Unexpected token (' - }, - - 'try {} catch (-x) {} ': { - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Unexpected token -' - }, - - - '\u203F = 10': { - index: 0, - lineNumber: 1, - column: 1, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'const x = 12, y;': { - index: 15, - lineNumber: 1, - column: 16, - message: 'Error: Line 1: Unexpected token ;' - }, - - 'const x, y = 12;': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected token ,' - }, - - 'const x;': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected token ;' - }, - - 'if(true) let a = 1;': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token let' - }, - - 'if(true) const a = 1;': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token const' - }, - - 'switch (c) { default: default: }': { - index: 30, - lineNumber: 1, - column: 31, - message: 'Error: Line 1: More than one default clause in switch statement' - }, - - 'new X()."s"': { - index: 8, - lineNumber: 1, - column: 9, - message: 'Error: Line 1: Unexpected string' - }, - - '/*': { - index: 2, - lineNumber: 1, - column: 3, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '/*\n\n\n': { - index: 5, - lineNumber: 4, - column: 1, - message: 'Error: Line 4: Unexpected token ILLEGAL' - }, - - '/**': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '/*\n\n*': { - index: 5, - lineNumber: 3, - column: 2, - message: 'Error: Line 3: Unexpected token ILLEGAL' - }, - - '/*hello': { - index: 7, - lineNumber: 1, - column: 8, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '/*hello *': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '\n]': { - index: 1, - lineNumber: 2, - column: 1, - message: 'Error: Line 2: Unexpected token ]' - }, - - '\r]': { - index: 1, - lineNumber: 2, - column: 1, - message: 'Error: Line 2: Unexpected token ]' - }, - - '\r\n]': { - index: 2, - lineNumber: 2, - column: 1, - message: 'Error: Line 2: Unexpected token ]' - }, - - '\n\r]': { - index: 2, - lineNumber: 3, - column: 1, - message: 'Error: Line 3: Unexpected token ]' - }, - - '//\r\n]': { - index: 4, - lineNumber: 2, - column: 1, - message: 'Error: Line 2: Unexpected token ]' - }, - - '//\n\r]': { - index: 4, - lineNumber: 3, - column: 1, - message: 'Error: Line 3: Unexpected token ]' - }, - - '/a\\\n/': { - index: 4, - lineNumber: 1, - column: 5, - message: 'Error: Line 1: Invalid regular expression: missing /' - }, - - '//\r \n]': { - index: 5, - lineNumber: 3, - column: 1, - message: 'Error: Line 3: Unexpected token ]' - }, - - '/*\r\n*/]': { - index: 6, - lineNumber: 2, - column: 3, - message: 'Error: Line 2: Unexpected token ]' - }, - - '/*\n\r*/]': { - index: 6, - lineNumber: 3, - column: 3, - message: 'Error: Line 3: Unexpected token ]' - }, - - '/*\r \n*/]': { - index: 7, - lineNumber: 3, - column: 3, - message: 'Error: Line 3: Unexpected token ]' - }, - - '\\\\': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '\\u005c': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - - '\\x': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '\\u0000': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '\u200C = []': { - index: 0, - lineNumber: 1, - column: 1, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '\u200D = []': { - index: 0, - lineNumber: 1, - column: 1, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '"\\': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - '"\\u': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected token ILLEGAL' - }, - - 'try { } catch() {}': { - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Unexpected token )' - }, - - 'return': { - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Illegal return statement' - }, - - 'break': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Illegal break statement' - }, - - 'continue': { - index: 8, - lineNumber: 1, - column: 9, - message: 'Error: Line 1: Illegal continue statement' - }, - - 'switch (x) { default: continue; }': { - index: 31, - lineNumber: 1, - column: 32, - message: 'Error: Line 1: Illegal continue statement' - }, - - 'do { x } *': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token *' - }, - - 'while (true) { break x; }': { - index: 22, - lineNumber: 1, - column: 23, - message: 'Error: Line 1: Undefined label \'x\'' - }, - - 'while (true) { continue x; }': { - index: 25, - lineNumber: 1, - column: 26, - message: 'Error: Line 1: Undefined label \'x\'' - }, - - 'x: while (true) { (function () { break x; }); }': { - index: 40, - lineNumber: 1, - column: 41, - message: 'Error: Line 1: Undefined label \'x\'' - }, - - 'x: while (true) { (function () { continue x; }); }': { - index: 43, - lineNumber: 1, - column: 44, - message: 'Error: Line 1: Undefined label \'x\'' - }, - - 'x: while (true) { (function () { break; }); }': { - index: 39, - lineNumber: 1, - column: 40, - message: 'Error: Line 1: Illegal break statement' - }, - - 'x: while (true) { (function () { continue; }); }': { - index: 42, - lineNumber: 1, - column: 43, - message: 'Error: Line 1: Illegal continue statement' - }, - - 'x: while (true) { x: while (true) { } }': { - index: 20, - lineNumber: 1, - column: 21, - message: 'Error: Line 1: Label \'x\' has already been declared' - }, - - '(function () { \'use strict\'; delete i; }())': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Delete of an unqualified identifier in strict mode.' - }, - - '(function () { \'use strict\'; with (i); }())': { - index: 28, - lineNumber: 1, - column: 29, - message: 'Error: Line 1: Strict mode code may not include a with statement' - }, - - 'function hello() {\'use strict\'; ({ i: 42, i: 42 }) }': { - index: 47, - lineNumber: 1, - column: 48, - message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' - }, - - 'function hello() {\'use strict\'; ({ hasOwnProperty: 42, hasOwnProperty: 42 }) }': { - index: 73, - lineNumber: 1, - column: 74, - message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' - }, - - 'function hello() {\'use strict\'; var eval = 10; }': { - index: 40, - lineNumber: 1, - column: 41, - message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; var arguments = 10; }': { - index: 45, - lineNumber: 1, - column: 46, - message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; try { } catch (eval) { } }': { - index: 51, - lineNumber: 1, - column: 52, - message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; try { } catch (arguments) { } }': { - index: 56, - lineNumber: 1, - column: 57, - message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; eval = 10; }': { - index: 32, - lineNumber: 1, - column: 33, - message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' - }, - - 'function hello() {\'use strict\'; arguments = 10; }': { - index: 32, - lineNumber: 1, - column: 33, - message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' - }, - - 'function hello() {\'use strict\'; ++eval; }': { - index: 38, - lineNumber: 1, - column: 39, - message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; --eval; }': { - index: 38, - lineNumber: 1, - column: 39, - message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; ++arguments; }': { - index: 43, - lineNumber: 1, - column: 44, - message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; --arguments; }': { - index: 43, - lineNumber: 1, - column: 44, - message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; eval++; }': { - index: 36, - lineNumber: 1, - column: 37, - message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; eval--; }': { - index: 36, - lineNumber: 1, - column: 37, - message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; arguments++; }': { - index: 41, - lineNumber: 1, - column: 42, - message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; arguments--; }': { - index: 41, - lineNumber: 1, - column: 42, - message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' - }, - - 'function hello() {\'use strict\'; function eval() { } }': { - index: 41, - lineNumber: 1, - column: 42, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; function arguments() { } }': { - index: 41, - lineNumber: 1, - column: 42, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - 'function eval() {\'use strict\'; }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - 'function arguments() {\'use strict\'; }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; (function eval() { }()) }': { - index: 42, - lineNumber: 1, - column: 43, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; (function arguments() { }()) }': { - index: 42, - lineNumber: 1, - column: 43, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - '(function eval() {\'use strict\'; })()': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - '(function arguments() {\'use strict\'; })()': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - 'function hello() {\'use strict\'; ({ s: function eval() { } }); }': { - index: 47, - lineNumber: 1, - column: 48, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }, - - '(function package() {\'use strict\'; })()': { - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() {\'use strict\'; ({ i: 10, set s(eval) { } }); }': { - index: 48, - lineNumber: 1, - column: 49, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function hello() {\'use strict\'; ({ set s(eval) { } }); }': { - index: 41, - lineNumber: 1, - column: 42, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function hello() {\'use strict\'; ({ s: function s(eval) { } }); }': { - index: 49, - lineNumber: 1, - column: 50, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function hello(eval) {\'use strict\';}': { - index: 15, - lineNumber: 1, - column: 16, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function hello(arguments) {\'use strict\';}': { - index: 15, - lineNumber: 1, - column: 16, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function hello() { \'use strict\'; function inner(eval) {} }': { - index: 48, - lineNumber: 1, - column: 49, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function hello() { \'use strict\'; function inner(arguments) {} }': { - index: 48, - lineNumber: 1, - column: 49, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - ' "\\1"; \'use strict\';': { - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { \'use strict\'; "\\1"; }': { - index: 33, - lineNumber: 1, - column: 34, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { \'use strict\'; 021; }': { - index: 33, - lineNumber: 1, - column: 34, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { \'use strict\'; ({ "\\1": 42 }); }': { - index: 36, - lineNumber: 1, - column: 37, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { \'use strict\'; ({ 021: 42 }); }': { - index: 36, - lineNumber: 1, - column: 37, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { "octal directive\\1"; "use strict"; }': { - index: 19, - lineNumber: 1, - column: 20, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { "octal directive\\1"; "octal directive\\2"; "use strict"; }': { - index: 19, - lineNumber: 1, - column: 20, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { "use strict"; function inner() { "octal directive\\1"; } }': { - index: 52, - lineNumber: 1, - column: 53, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }, - - 'function hello() { "use strict"; var implements; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var interface; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var package; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var private; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var protected; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var public; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var static; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var yield; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello() { "use strict"; var let; }': { - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function hello(static) { "use strict"; }': { - index: 15, - lineNumber: 1, - column: 16, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function static() { "use strict"; }': { - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'var yield': { - index: 4, - lineNumber: 1, - column: 5, - message: 'Error: Line 1: Unexpected token yield' - }, - - 'var let': { - index: 4, - lineNumber: 1, - column: 5, - message: 'Error: Line 1: Unexpected token let' - }, - - '"use strict"; function static() { }': { - index: 23, - lineNumber: 1, - column: 24, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function a(t, t) { "use strict"; }': { - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' - }, - - 'function a(eval) { "use strict"; }': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - 'function a(package) { "use strict"; }': { - index: 11, - lineNumber: 1, - column: 12, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'function a() { "use strict"; function b(t, t) { }; }': { - index: 43, - lineNumber: 1, - column: 44, - message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' - }, - - '(function a(t, t) { "use strict"; })': { - index: 15, - lineNumber: 1, - column: 16, - message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' - }, - - 'function a() { "use strict"; (function b(t, t) { }); }': { - index: 44, - lineNumber: 1, - column: 45, - message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' - }, - - '(function a(eval) { "use strict"; })': { - index: 12, - lineNumber: 1, - column: 13, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }, - - '(function a(package) { "use strict"; })': { - index: 12, - lineNumber: 1, - column: 13, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }, - - 'var': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'let': { - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Unexpected end of input' - }, - - 'const': { - index: 5, - lineNumber: 1, - column: 6, - message: 'Error: Line 1: Unexpected end of input' - } - - }, - - 'API': { - 'parse()': { - call: 'parse', - args: [], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'undefined' - } - }] - } - }, - - 'parse(null)': { - call: 'parse', - args: [null], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: null - } - }] - } - }, - - 'parse(42)': { - call: 'parse', - args: [42], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42 - } - }] - } - }, - - 'parse(true)': { - call: 'parse', - args: [true], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: true - } - }] - } - }, - - 'parse(undefined)': { - call: 'parse', - args: [void 0], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'undefined' - } - }] - } - }, - - 'parse(new String("test"))': { - call: 'parse', - args: [new String('test')], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Identifier', - name: 'test' - } - }] - } - }, - - 'parse(new Number(42))': { - call: 'parse', - args: [new Number(42)], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 42 - } - }] - } - }, - - 'parse(new Boolean(true))': { - call: 'parse', - args: [new Boolean(true)], - result: { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: true - } - }] - } - }, - - 'Syntax': { - property: 'Syntax', - result: { - AssignmentExpression: 'AssignmentExpression', - ArrayExpression: 'ArrayExpression', - BlockStatement: 'BlockStatement', - BinaryExpression: 'BinaryExpression', - BreakStatement: 'BreakStatement', - CallExpression: 'CallExpression', - CatchClause: 'CatchClause', - ConditionalExpression: 'ConditionalExpression', - ContinueStatement: 'ContinueStatement', - DoWhileStatement: 'DoWhileStatement', - DebuggerStatement: 'DebuggerStatement', - EmptyStatement: 'EmptyStatement', - ExpressionStatement: 'ExpressionStatement', - ForStatement: 'ForStatement', - ForInStatement: 'ForInStatement', - FunctionDeclaration: 'FunctionDeclaration', - FunctionExpression: 'FunctionExpression', - Identifier: 'Identifier', - IfStatement: 'IfStatement', - Literal: 'Literal', - LabeledStatement: 'LabeledStatement', - LogicalExpression: 'LogicalExpression', - MemberExpression: 'MemberExpression', - NewExpression: 'NewExpression', - ObjectExpression: 'ObjectExpression', - Program: 'Program', - Property: 'Property', - ReturnStatement: 'ReturnStatement', - SequenceExpression: 'SequenceExpression', - SwitchStatement: 'SwitchStatement', - SwitchCase: 'SwitchCase', - ThisExpression: 'ThisExpression', - ThrowStatement: 'ThrowStatement', - TryStatement: 'TryStatement', - UnaryExpression: 'UnaryExpression', - UpdateExpression: 'UpdateExpression', - VariableDeclaration: 'VariableDeclaration', - VariableDeclarator: 'VariableDeclarator', - WhileStatement: 'WhileStatement', - WithStatement: 'WithStatement' - } - } - - }, - - 'Tolerant parse': { - 'return': { - type: 'Program', - body: [{ - type: 'ReturnStatement', - 'argument': null, - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - } - }], - range: [0, 6], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 6 } - }, - errors: [{ - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Illegal return statement' - }] - }, - - '(function () { \'use strict\'; with (i); }())': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '\'use strict\'', - range: [15, 27], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 27 } - } - }, - range: [15, 28], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 28 } - } - }, { - type: 'WithStatement', - object: { - type: 'Identifier', - name: 'i', - range: [35, 36], - loc: { - start: { line: 1, column: 35 }, - end: { line: 1, column: 36 } - } - }, - body: { - type: 'EmptyStatement', - range: [37, 38], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 38 } - } - }, - range: [29, 38], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 38 } - } - }], - range: [13, 40], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 40 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 40], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 40 } - } - }, - 'arguments': [], - range: [1, 42], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 42 } - } - }, - range: [0, 43], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 43 } - } - }], - range: [0, 43], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 43 } - }, - errors: [{ - index: 29, - lineNumber: 1, - column: 30, - message: 'Error: Line 1: Strict mode code may not include a with statement' - }] - }, - - '(function () { \'use strict\'; 021 }())': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'CallExpression', - callee: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '\'use strict\'', - range: [15, 27], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 27 } - } - }, - range: [15, 28], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 28 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 17, - raw: "021", - range: [29, 32], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 32 } - } - }, - range: [29, 33], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 33 } - } - }], - range: [13, 34], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [1, 34], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 34 } - } - }, - 'arguments': [], - range: [1, 36], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 36 } - } - }, - range: [0, 37], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 37 } - } - }], - range: [0, 37], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 37 } - }, - errors: [{ - index: 29, - lineNumber: 1, - column: 30, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }] - }, - - '"use strict"; delete x': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UnaryExpression', - operator: 'delete', - argument: { - type: 'Identifier', - name: 'x', - range: [21, 22], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 22 } - } - }, - prefix: true, - range: [14, 22], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 22 } - } - }, - range: [14, 22], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 22 } - } - }], - range: [0, 22], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 22 } - }, - errors: [{ - index: 22, - lineNumber: 1, - column: 23, - message: 'Error: Line 1: Delete of an unqualified identifier in strict mode.' - }] - }, - - '"use strict"; try {} catch (eval) {}': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [18, 20], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 20 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'eval', - range: [28, 32], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 32 } - } - }, - body: { - type: 'BlockStatement', - body: [], - range: [34, 36], - loc: { - start: { line: 1, column: 34 }, - end: { line: 1, column: 36 } - } - }, - range: [21, 36], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 36 } - } - }], - finalizer: null, - range: [14, 36], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 36 } - } - }], - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - }, - errors: [{ - index: 32, - lineNumber: 1, - column: 33, - message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; try {} catch (arguments) {}': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'TryStatement', - block: { - type: 'BlockStatement', - body: [], - range: [18, 20], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 20 } - } - }, - guardedHandlers: [], - handlers: [{ - type: 'CatchClause', - param: { - type: 'Identifier', - name: 'arguments', - range: [28, 37], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 37 } - } - }, - body: { - type: 'BlockStatement', - body: [], - range: [39, 41], - loc: { - start: { line: 1, column: 39 }, - end: { line: 1, column: 41 } - } - }, - range: [21, 41], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 41 } - } - }], - finalizer: null, - range: [14, 41], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 41 } - } - }], - range: [0, 41], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 41 } - }, - errors: [{ - index: 37, - lineNumber: 1, - column: 38, - message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; var eval;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'eval', - range: [18, 22], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 22 } - } - }, - init: null, - range: [18, 22], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 22 } - } - }], - kind: 'var', - range: [14, 23], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 23 } - } - }], - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - }, - errors: [{ - index: 22, - lineNumber: 1, - column: 23, - message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; var arguments;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'arguments', - range: [18, 27], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 27 } - } - }, - init: null, - range: [18, 27], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 27 } - } - }], - kind: 'var', - range: [14, 28], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 28 } - } - }], - range: [0, 28], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 28 } - }, - errors: [{ - index: 27, - lineNumber: 1, - column: 28, - message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; eval = 0;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'eval', - range: [14, 18], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 18 } - } - }, - right: { - type: 'Literal', - value: 0, - raw: '0', - range: [21, 22], - loc: { - start: { line: 1, column: 21 }, - end: { line: 1, column: 22 } - } - }, - range: [14, 22], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 22 } - } - }, - range: [14, 23], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 23 } - } - }], - range: [0, 23], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 23 } - }, - errors: [{ - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' - }] - }, - - '"use strict"; eval++;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'eval', - range: [14, 18], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 18 } - } - }, - prefix: false, - range: [14, 20], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 20 } - } - }, - range: [14, 21], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 21 } - } - }], - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - }, - errors: [{ - index: 18, - lineNumber: 1, - column: 19, - message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' - }] - }, - - '"use strict"; --eval;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'eval', - range: [16, 20], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 20 } - } - }, - prefix: true, - range: [14, 20], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 20 } - } - }, - range: [14, 21], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 21 } - } - }], - range: [0, 21], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 21 } - }, - errors: [{ - index: 20, - lineNumber: 1, - column: 21, - message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' - }] - }, - - '"use strict"; arguments = 0;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'arguments', - range: [14, 23], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 23 } - } - }, - right: { - type: 'Literal', - value: 0, - raw: '0', - range: [26, 27], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 27 } - } - }, - range: [14, 27], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 27 } - } - }, - range: [14, 28], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 28 } - } - }], - range: [0, 28], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 28 } - }, - errors: [{ - index: 14, - lineNumber: 1, - column: 15, - message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' - }] - }, - - '"use strict"; arguments--;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Identifier', - name: 'arguments', - range: [14, 23], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 23 } - } - }, - prefix: false, - range: [14, 25], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 25 } - } - }, - range: [14, 26], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 26 } - } - }], - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - }, - errors: [{ - index: 23, - lineNumber: 1, - column: 24, - message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' - }] - }, - - '"use strict"; ++arguments;': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Identifier', - name: 'arguments', - range: [16, 25], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 25 } - } - }, - prefix: true, - range: [14, 25], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 25 } - } - }, - range: [14, 26], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 26 } - } - }], - range: [0, 26], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 26 } - }, - errors: [{ - index: 25, - lineNumber: 1, - column: 26, - message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' - }] - }, - - - '"use strict";x={y:1,y:1}': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [13, 14], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 14 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'y', - range: [16, 17], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 17 } - } - }, - value: { - type: 'Literal', - value: 1, - raw: '1', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - kind: 'init', - range: [16, 19], - loc: { - start: { line: 1, column: 16 }, - end: { line: 1, column: 19 } - } - }, { - type: 'Property', - key: { - type: 'Identifier', - name: 'y', - range: [20, 21], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 21 } - } - }, - value: { - type: 'Literal', - value: 1, - raw: '1', - range: [22, 23], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 23 } - } - }, - kind: 'init', - range: [20, 23], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 23 } - } - }], - range: [15, 24], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 24 } - } - }, - range: [13, 24], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 24 } - } - }, - range: [13, 24], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 24 } - } - }], - range: [0, 24], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 24 } - }, - errors: [{ - index: 23, - lineNumber: 1, - column: 24, - message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' - }] - }, - - '"use strict"; function eval() {};': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'eval', - range: [23, 27], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 27 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [30, 32], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 32 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 32], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 32 } - } - }, { - type: 'EmptyStatement', - range: [32, 33], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 33 } - } - }], - range: [0, 33], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 33 } - }, - errors: [{ - index: 23, - lineNumber: 1, - column: 24, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; function arguments() {};': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'arguments', - range: [23, 32], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 32 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [35, 37], - loc: { - start: { line: 1, column: 35 }, - end: { line: 1, column: 37 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 37], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 37 } - } - }, { - type: 'EmptyStatement', - range: [37, 38], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 38 } - } - }], - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - }, - errors: [{ - index: 23, - lineNumber: 1, - column: 24, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; function interface() {};': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'interface', - range: [23, 32], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 32 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [35, 37], - loc: { - start: { line: 1, column: 35 }, - end: { line: 1, column: 37 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 37], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 37 } - } - }, { - type: 'EmptyStatement', - range: [37, 38], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 38 } - } - }], - range: [0, 38], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 38 } - }, - errors: [{ - index: 23, - lineNumber: 1, - column: 24, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }] - }, - - '"use strict"; (function eval() {});': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'eval', - range: [24, 28], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 28 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [31, 33], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 33 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 33], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 33 } - } - }, - range: [14, 35], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 35 } - } - }], - range: [0, 35], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 35 } - }, - errors: [{ - index: 24, - lineNumber: 1, - column: 25, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; (function arguments() {});': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'arguments', - range: [24, 33], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 33 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [36, 38], - loc: { - start: { line: 1, column: 36 }, - end: { line: 1, column: 38 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 38], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 38 } - } - }, - range: [14, 40], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 40 } - } - }], - range: [0, 40], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 40 } - }, - errors: [{ - index: 24, - lineNumber: 1, - column: 25, - message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' - }] - }, - - '"use strict"; (function interface() {});': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'interface', - range: [24, 33], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 33 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [36, 38], - loc: { - start: { line: 1, column: 36 }, - end: { line: 1, column: 38 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 38], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 38 } - } - }, - range: [14, 40], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 40 } - } - }], - range: [0, 40], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 40 } - }, - errors: [{ - index: 24, - lineNumber: 1, - column: 25, - message: 'Error: Line 1: Use of future reserved word in strict mode' - }] - }, - - '"use strict"; function f(eval) {};': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'f', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }, - params: [{ - type: 'Identifier', - name: 'eval', - range: [25, 29], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 29 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [31, 33], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 33 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 33], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 33 } - } - }, { - type: 'EmptyStatement', - range: [33, 34], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 34 } - } - }], - range: [0, 34], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 34 } - }, - errors: [{ - index: 25, - lineNumber: 1, - column: 26, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }] - }, - - '"use strict"; function f(arguments) {};': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'f', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }, - params: [{ - type: 'Identifier', - name: 'arguments', - range: [25, 34], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 34 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [36, 38], - loc: { - start: { line: 1, column: 36 }, - end: { line: 1, column: 38 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 38], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 38 } - } - }, { - type: 'EmptyStatement', - range: [38, 39], - loc: { - start: { line: 1, column: 38 }, - end: { line: 1, column: 39 } - } - }], - range: [0, 39], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 39 } - }, - errors: [{ - index: 25, - lineNumber: 1, - column: 26, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }] - }, - - '"use strict"; function f(foo, foo) {};': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'f', - range: [23, 24], - loc: { - start: { line: 1, column: 23 }, - end: { line: 1, column: 24 } - } - }, - params: [{ - type: 'Identifier', - name: 'foo', - range: [25, 28], - loc: { - start: { line: 1, column: 25 }, - end: { line: 1, column: 28 } - } - }, { - type: 'Identifier', - name: 'foo', - range: [31, 34], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 34 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [36, 38], - loc: { - start: { line: 1, column: 36 }, - end: { line: 1, column: 38 } - } - }, - rest: null, - generator: false, - expression: false, - range: [14, 38], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 38 } - } - }, { - type: 'EmptyStatement', - range: [38, 39], - loc: { - start: { line: 1, column: 38 }, - end: { line: 1, column: 39 } - } - }], - range: [0, 39], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 39 } - }, - errors: [{ - index: 31, - lineNumber: 1, - column: 32, - message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' - }] - }, - - '"use strict"; (function f(eval) {});': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'f', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - params: [{ - type: 'Identifier', - name: 'eval', - range: [26, 30], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 30 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [32, 34], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 34], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 34 } - } - }, - range: [14, 36], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 36 } - } - }], - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - }, - errors: [{ - index: 26, - lineNumber: 1, - column: 27, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }] - }, - - - '"use strict"; (function f(arguments) {});': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'f', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - params: [{ - type: 'Identifier', - name: 'arguments', - range: [26, 35], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 35 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [37, 39], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 39 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 39], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 39 } - } - }, - range: [14, 41], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 41 } - } - }], - range: [0, 41], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 41 } - }, - errors: [{ - index: 26, - lineNumber: 1, - column: 27, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }] - }, - - '"use strict"; (function f(foo, foo) {});': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'FunctionExpression', - id: { - type: 'Identifier', - name: 'f', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - params: [{ - type: 'Identifier', - name: 'foo', - range: [26, 29], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 29 } - } - }, { - type: 'Identifier', - name: 'foo', - range: [32, 35], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 35 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [37, 39], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 39 } - } - }, - rest: null, - generator: false, - expression: false, - range: [15, 39], - loc: { - start: { line: 1, column: 15 }, - end: { line: 1, column: 39 } - } - }, - range: [14, 41], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 41 } - } - }], - range: [0, 41], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 41 } - }, - errors: [{ - index: 32, - lineNumber: 1, - column: 33, - message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' - }] - }, - - '"use strict"; x = { set f(eval) {} }' : { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Identifier', - name: 'x', - range: [14, 15], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 15 } - } - }, - right: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'f', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - value : { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'eval', - range: [26, 30], - loc: { - start: { line: 1, column: 26 }, - end: { line: 1, column: 30 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [32, 34], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [32, 34], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 34 } - } - }, - kind: 'set', - range: [20, 34], - loc: { - start: { line: 1, column: 20 }, - end: { line: 1, column: 34 } - } - }], - range: [18, 36], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 36 } - } - }, - range: [14, 36], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 36 } - } - }, - range: [14, 36], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 36 } - } - }], - range: [0, 36], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 36 } - }, - errors: [{ - index: 26, - lineNumber: 1, - column: 27, - message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' - }] - }, - - 'function hello() { "octal directive\\1"; "use strict"; }': { - type: 'Program', - body: [{ - type: 'FunctionDeclaration', - id: { - type: 'Identifier', - name: 'hello', - range: [9, 14], - loc: { - start: { line: 1, column: 9 }, - end: { line: 1, column: 14 } - } - }, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'octal directive\u0001', - raw: '"octal directive\\1"', - range: [19, 38], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 38 } - } - }, - range: [19, 39], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 39 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [40, 52], - loc: { - start: { line: 1, column: 40 }, - end: { line: 1, column: 52 } - } - }, - range: [40, 53], - loc: { - start: { line: 1, column: 40 }, - end: { line: 1, column: 53 } - } - }], - range: [17, 55], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 55 } - } - }, - rest: null, - generator: false, - expression: false, - range: [0, 55], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 55 } - } - }], - range: [0, 55], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 55 } - }, - errors: [{ - index: 19, - lineNumber: 1, - column: 20, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }] - }, - - '"\\1"; \'use strict\';': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: '\u0001', - raw: '"\\1"', - range: [0, 4], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 4 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, { - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '\'use strict\'', - range: [6, 18], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 18 } - } - }, - range: [6, 19], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 19 } - } - }], - range: [0, 19], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 19 } - }, - errors: [{ - index: 0, - lineNumber: 1, - column: 1, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }] - }, - - '"use strict"; var x = { 014: 3}': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - init: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Literal', - value: 12, - raw: '014', - range: [24, 27], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 27 } - } - }, - value: { - type: 'Literal', - value: 3, - raw: '3', - range: [29, 30], - loc: { - start: { line: 1, column: 29 }, - end: { line: 1, column: 30 } - } - }, - kind: 'init', - range: [24, 30], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 30 } - } - }], - range: [22, 31], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 31 } - } - }, - range: [18, 31], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 31 } - } - }], - kind: 'var', - range: [14, 31], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 31 } - } - }], - range: [0, 31], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 31 } - }, - errors: [{ - index: 24, - lineNumber: 1, - column: 25, - message: 'Error: Line 1: Octal literals are not allowed in strict mode.' - }] - }, - - '"use strict"; var x = { get i() {}, get i() {} }': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - init: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'i', - range: [28, 29], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 29 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [32, 34], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 34 } - } - }, - rest: null, - generator: false, - expression: false, - range: [32, 34], - loc: { - start: { line: 1, column: 32 }, - end: { line: 1, column: 34 } - } - }, - kind: 'get', - range: [24, 34], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 34 } - } - }, { - type: 'Property', - key: { - type: 'Identifier', - name: 'i', - range: [40, 41], - loc: { - start: { line: 1, column: 40 }, - end: { line: 1, column: 41 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [44, 46], - loc: { - start: { line: 1, column: 44 }, - end: { line: 1, column: 46 } - } - }, - rest: null, - generator: false, - expression: false, - range: [44, 46], - loc: { - start: { line: 1, column: 44 }, - end: { line: 1, column: 46 } - } - }, - kind: 'get', - range: [36, 46], - loc: { - start: { line: 1, column: 36 }, - end: { line: 1, column: 46 } - } - }], - range: [22, 48], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 48 } - } - }, - range: [18, 48], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 48 } - } - }], - kind: 'var', - range: [14, 48], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 48 } - } - }], - range: [0, 48], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 48 } - }, - errors: [{ - index: 46, - lineNumber: 1, - column: 47, - message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' - }] - }, - - '"use strict"; var x = { i: 42, get i() {} }': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - init: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'i', - range: [24, 25], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 25 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [27, 29], - loc: { - start: { line: 1, column: 27 }, - end: { line: 1, column: 29 } - } - }, - kind: 'init', - range: [24, 29], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 29 } - } - }, { - type: 'Property', - key: { - type: 'Identifier', - name: 'i', - range: [35, 36], - loc: { - start: { line: 1, column: 35 }, - end: { line: 1, column: 36 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [39, 41], - loc: { - start: { line: 1, column: 39 }, - end: { line: 1, column: 41 } - } - }, - rest: null, - generator: false, - expression: false, - range: [39, 41], - loc: { - start: { line: 1, column: 39 }, - end: { line: 1, column: 41 } - } - }, - kind: 'get', - range: [31, 41], - loc: { - start: { line: 1, column: 31 }, - end: { line: 1, column: 41 } - } - }], - range: [22, 43], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 43 } - } - }, - range: [18, 43], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 43 } - } - }], - kind: 'var', - range: [14, 43], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 43 } - } - }], - range: [0, 43], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 43 } - }, - errors: [{ - index: 41, - lineNumber: 1, - column: 42, - message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' - }] - }, - - '"use strict"; var x = { set i(x) {}, i: 42 }': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'Literal', - value: 'use strict', - raw: '"use strict"', - range: [0, 12], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 12 } - } - }, - range: [0, 13], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 13 } - } - }, { - type: 'VariableDeclaration', - declarations: [{ - type: 'VariableDeclarator', - id: { - type: 'Identifier', - name: 'x', - range: [18, 19], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 19 } - } - }, - init: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 'i', - range: [28, 29], - loc: { - start: { line: 1, column: 28 }, - end: { line: 1, column: 29 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [{ - type: 'Identifier', - name: 'x', - range: [30, 31], - loc: { - start: { line: 1, column: 30 }, - end: { line: 1, column: 31 } - } - }], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [33, 35], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 35 } - } - }, - rest: null, - generator: false, - expression: false, - range: [33, 35], - loc: { - start: { line: 1, column: 33 }, - end: { line: 1, column: 35 } - } - }, - kind: 'set', - range: [24, 35], - loc: { - start: { line: 1, column: 24 }, - end: { line: 1, column: 35 } - } - }, { - type: 'Property', - key: { - type: 'Identifier', - name: 'i', - range: [37, 38], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 38 } - } - }, - value: { - type: 'Literal', - value: 42, - raw: '42', - range: [40, 42], - loc: { - start: { line: 1, column: 40 }, - end: { line: 1, column: 42 } - } - }, - kind: 'init', - range: [37, 42], - loc: { - start: { line: 1, column: 37 }, - end: { line: 1, column: 42 } - } - }], - range: [22, 44], - loc: { - start: { line: 1, column: 22 }, - end: { line: 1, column: 44 } - } - }, - range: [18, 44], - loc: { - start: { line: 1, column: 18 }, - end: { line: 1, column: 44 } - } - }], - kind: 'var', - range: [14, 44], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 44 } - } - }], - range: [0, 44], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 44 } - }, - errors: [{ - index: 42, - lineNumber: 1, - column: 43, - message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' - }] - - - }, - - '({ set s() { } })': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'ObjectExpression', - properties: [{ - type: 'Property', - key: { - type: 'Identifier', - name: 's', - range: [7, 8], - loc: { - start: { line: 1, column: 7 }, - end: { line: 1, column: 8 } - } - }, - value: { - type: 'FunctionExpression', - id: null, - params: [], - defaults: [], - body: { - type: 'BlockStatement', - body: [], - range: [11, 14], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 14 } - } - }, - rest: null, - generator: false, - expression: false, - range: [11, 14], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 14 } - } - }, - kind: 'set', - range: [3, 14], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 14 } - } - }], - range: [1, 16], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - } - }], - range: [0, 17], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 17 } - }, - errors: [{ - index: 9, - lineNumber: 1, - column: 10, - message: 'Error: Line 1: Unexpected token )' - }] - }, - - 'foo("bar") = baz': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'CallExpression', - callee: { - type: 'Identifier', - name: 'foo', - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - 'arguments': [{ - type: 'Literal', - value: 'bar', - raw: '"bar"', - range: [4, 9], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 9 } - } - }], - range: [0, 10], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 10 } - } - }, - right: { - type: 'Identifier', - name: 'baz', - range: [13, 16], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }], - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - }, - errors: [{ - index: 10, - lineNumber: 1, - column: 11, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }] - }, - - '1 = 2': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'AssignmentExpression', - operator: '=', - left: { - type: 'Literal', - value: 1, - raw: '1', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - right: { - type: 'Literal', - value: 2, - raw: '2', - range: [4, 5], - loc: { - start: { line: 1, column: 4 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }, - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - } - }], - range: [0, 5], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 5 } - }, - errors: [{ - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }] - }, - - '3++': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '++', - argument: { - type: 'Literal', - value: 3, - raw: '3', - range: [0, 1], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 1 } - } - }, - prefix: false, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }], - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - }, - errors: [{ - index: 1, - lineNumber: 1, - column: 2, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }] - }, - - '--4': { - type: 'Program', - body: [{ - type: 'ExpressionStatement', - expression: { - type: 'UpdateExpression', - operator: '--', - argument: { - type: 'Literal', - value: 4, - raw: '4', - range: [2, 3], - loc: { - start: { line: 1, column: 2 }, - end: { line: 1, column: 3 } - } - }, - prefix: true, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }, - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - } - }], - range: [0, 3], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 3 } - }, - errors: [{ - index: 3, - lineNumber: 1, - column: 4, - message: 'Error: Line 1: Invalid left-hand side in assignment' - }] - }, - - 'for (5 in []) {}': { - type: 'Program', - body: [{ - type: 'ForInStatement', - left: { - type: 'Literal', - value: 5, - raw: '5', - range: [5, 6], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 6 } - } - }, - right: { - type: 'ArrayExpression', - elements: [], - range: [10, 12], - loc: { - start: { line: 1, column: 10 }, - end: { line: 1, column: 12 } - } - }, - body: { - type: 'BlockStatement', - body: [], - range: [14, 16], - loc: { - start: { line: 1, column: 14 }, - end: { line: 1, column: 16 } - } - }, - each: false, - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - } - }], - range: [0, 16], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 16 } - }, - errors: [{ - index: 6, - lineNumber: 1, - column: 7, - message: 'Error: Line 1: Invalid left-hand side in for-in' - }] - } - - - } -}; - diff --git a/spec/fixture/node_modules/grunt/node_modules/js-yaml/package.json b/spec/fixture/node_modules/grunt/node_modules/js-yaml/package.json deleted file mode 100644 index 112abb2b..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/js-yaml/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "js-yaml", - "version": "2.0.5", - "description": "YAML 1.2 parser and serializer", - "keywords": [ - "yaml", - "parser", - "serializer", - "pyyaml" - ], - "homepage": "https://github.com/nodeca/js-yaml", - "author": { - "name": "Dervus Grim", - "email": "dervus@lavabit.com" - }, - "contributors": [ - { - "name": "Aleksey V Zapparov", - "email": "ixti@member.fsf.org", - "url": "http://www.ixti.net/" - }, - { - "name": "Martin Grenfell", - "email": "martin.grenfell@gmail.com", - "url": "http://got-ravings.blogspot.com" - } - ], - "bugs": { - "url": "https://github.com/nodeca/js-yaml/issues" - }, - "license": { - "type": "MIT", - "url": "https://github.com/nodeca/js-yaml/blob/master/LICENSE" - }, - "repository": { - "type": "git", - "url": "git://github.com/nodeca/js-yaml.git" - }, - "main": "./index.js", - "bin": { - "js-yaml": "bin/js-yaml.js" - }, - "scripts": { - "test": "make test" - }, - "dependencies": { - "argparse": "~ 0.1.11", - "esprima": "~ 1.0.2" - }, - "devDependencies": { - "mocha": "*" - }, - "engines": { - "node": ">= 0.6.0" - }, - "_id": "js-yaml@2.0.5", - "dist": { - "shasum": "a25ae6509999e97df278c6719da11bd0687743a8", - "tarball": "http://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz" - }, - "_from": "js-yaml@~2.0.5", - "_resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", - "_npmVersion": "1.2.14", - "_npmUser": { - "name": "vitaly", - "email": "vitaly@rcdesign.ru" - }, - "maintainers": [ - { - "name": "vitaly", - "email": "vitaly@rcdesign.ru" - } - ], - "directories": {}, - "_shasum": "a25ae6509999e97df278c6719da11bd0687743a8", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/lodash/README.md b/spec/fixture/node_modules/grunt/node_modules/lodash/README.md deleted file mode 100644 index 55dae80f..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/lodash/README.md +++ /dev/null @@ -1,140 +0,0 @@ -# Lo-Dash v0.9.2 - -A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features). - -## Download - - * [Development build](https://raw.github.com/lodash/lodash/0.9.2/lodash.js) - * [Production build](https://raw.github.com/lodash/lodash/0.9.2/lodash.min.js) - * [Underscore build](https://raw.github.com/lodash/lodash/0.9.2/lodash.underscore.min.js) tailored for projects already using Underscore - * CDN copies of ≤ v0.9.2’s [Production](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.9.2/lodash.min.js), [Underscore](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.9.2/lodash.underscore.min.js), and [Development](http://cdnjs.cloudflare.com/ajax/libs/lodash.js/0.9.2/lodash.js) builds are available on [cdnjs](http://cdnjs.com/) thanks to [CloudFlare](http://www.cloudflare.com/) - * For optimal file size, [create a custom build](http://lodash.com/custom-builds) with only the features you need - -## Dive in - -We’ve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests). - -Create your own benchmarks at [jsPerf](http://jsperf.com), or [search](http://jsperf.com/search?q=lodash) for existing ones. - -For a list of upcoming features, check out our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). - -## Screencasts - -For more information check out these screencasts over Lo-Dash: - - * [Introducing Lo-Dash](https://vimeo.com/44154599) - * [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601) - * [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600) - * [Unit testing in Lo-Dash](https://vimeo.com/45865290) - * [Lo-Dash’s approach to native method use](https://vimeo.com/48576012) - -## Features - - * AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.) - * [_.clone](http://lodash.com/docs#clone) supports *“deepâ€* cloning - * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument - * [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early - * [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties - * [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties - * [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor - * [_.lateBind](http://lodash.com/docs#lateBind) for late binding - * [_.merge](http://lodash.com/docs#merge) for a *“deepâ€* [_.extend](http://lodash.com/docs#extend) - * [_.partial](http://lodash.com/docs#partial) for partial application without `this` binding - * [_.pick](http://lodash.com/docs#pick) and [_.omit](http://lodash.com/docs#omit) accepts `callback` and `thisArg` arguments - * [_.template](http://lodash.com/docs#template) supports [ES6 delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6) and utilizes [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) for easier debugging - * [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray), - [and more…](http://lodash.com/docs "_.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings - -## Support - -Lo-Dash has been tested in at least Chrome 5~23, Firefox 1~16, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.14, Narwhal 0.3.2, RingoJS 0.8, and Rhino 1.7RC5. - -## Installation and usage - -In browsers: - -```html - -``` - -Using [npm](http://npmjs.org/): - -```bash -npm install lodash - -npm install -g lodash -npm link lodash -``` - -In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): - -```js -var _ = require('lodash'); -``` - -**Note:** If Lo-Dash is installed globally, [run `npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before requiring it. - -In [RingoJS v0.7.0-](http://ringojs.org/): - -```js -var _ = require('lodash')._; -``` - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader like [RequireJS](http://requirejs.org/): - -```js -require({ - 'paths': { - 'underscore': 'path/to/lodash' - } -}, -['underscore'], function(_) { - console.log(_.VERSION); -}); -``` - -## Resolved Underscore.js issues - - * Allow iteration of objects with a `length` property [[#799](https://github.com/documentcloud/underscore/pull/799), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L545-551)] - * Fix cross-browser object iteration bugs [[#60](https://github.com/documentcloud/underscore/issues/60), [#376](https://github.com/documentcloud/underscore/issues/376), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L558-582)] - * Methods should work on pages with incorrectly shimmed native methods [[#7](https://github.com/documentcloud/underscore/issues/7), [#742](https://github.com/documentcloud/underscore/issues/742), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L140-146)] - * `_.isEmpty` should support jQuery/MooTools DOM query collections [[#690](https://github.com/documentcloud/underscore/pull/690), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L747-752)] - * `_.isObject` should avoid V8 bug [#2291](http://code.google.com/p/8/issues/detail?id=2291) [[#605](https://github.com/documentcloud/underscore/issues/605), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L828-840)] - * `_.keys` should work with `arguments` objects cross-browser [[#396](https://github.com/documentcloud/underscore/issues/396), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L921-923)] - * `_.range` should coerce arguments to numbers [[#634](https://github.com/documentcloud/underscore/issues/634), [#683](https://github.com/documentcloud/underscore/issues/683), [test](https://github.com/lodash/lodash/blob/0.9.2/test/test.js#L1337-1340)] - -## Release Notes - -### v0.9.2 - - * Added `fromIndex` argument to `_.contains` - * Added `moduleId` build option - * Added Closure Compiler *“simpleâ€* optimizations to the build process - * Added support for strings in `_.max` and `_.min` - * Added support for ES6 template delimiters to `_.template` - * Ensured re-minification of Lo-Dash by third parties avoids Closure Compiler bugs - * Optimized `_.every`, `_.find`, `_.some`, and `_.uniq` - -The full changelog is available [here](https://github.com/lodash/lodash/wiki/Changelog). - -## BestieJS - -Lo-Dash is part of the [BestieJS](https://github.com/bestiejs) *“Best in Classâ€* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation. - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](http://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](http://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](http://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://iceddev.com/) | [Kit Cambridge](http://kitcambridge.github.io/) | [Mathias Bynens](http://mathiasbynens.be/) | diff --git a/spec/fixture/node_modules/grunt/node_modules/lodash/lodash.js b/spec/fixture/node_modules/grunt/node_modules/lodash/lodash.js deleted file mode 100644 index 9eae931c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/lodash/lodash.js +++ /dev/null @@ -1,4258 +0,0 @@ -/*! - * Lo-Dash v0.9.2 - * (c) 2012 John-David Dalton - * Based on Underscore.js 1.4.2 - * (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. - * Available under MIT license - */ -;(function(window, undefined) { - - /** Detect free variable `exports` */ - var freeExports = typeof exports == 'object' && exports; - - /** Detect free variable `global` and use it as `window` */ - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal) { - window = freeGlobal; - } - - /** Used for array and object method references */ - var arrayRef = [], - // avoid a Closure Compiler bug by creatively creating an object - objectRef = new function(){}; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = objectRef; - - /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */ - var largeArraySize = 30; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = window._; - - /** Used to detect template delimiter values that require a with-statement */ - var reComplexDelimiter = /[-?+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/; - - /** Used to match HTML entities */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#x27);/g; - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to insert the data object variable into compiled template source */ - var reInsertVariable = /(?:__e|__t = )\(\s*(?![\d\s"']|this\.)/g; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - (objectRef.valueOf + '') - .replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&') - .replace(/valueOf|for [^\]]+/g, '.+?') + '$' - ); - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6 - */ - var reEsTemplate = /\$\{((?:(?=\\?)\\?[\s\S])*?)}/g; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to match HTML characters */ - var reUnescapedHtml = /[&<>"']/g; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowed = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** Native method shortcuts */ - var ceil = Math.ceil, - concat = arrayRef.concat, - floor = Math.floor, - getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectRef.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectRef.propertyIsEnumerable, - slice = arrayRef.slice, - toString = objectRef.toString; - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind, - nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = window.isFinite, - nativeIsNaN = window.isNaN, - nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeRandom = Math.random; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** - * Detect the JScript [[DontEnum]] bug: - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well. - */ - var hasDontEnumBug; - - /** Detect if own properties are iterated after inherited properties (IE < 9) */ - var iteratesOwnLast; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects - * incorrectly: - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - */ - var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 }, - arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]); - - /** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */ - var noArgsEnum = true; - - (function() { - var props = []; - function ctor() { this.x = 1; } - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var prop in new ctor) { props.push(prop); } - for (prop in arguments) { noArgsEnum = !prop; } - - hasDontEnumBug = !/valueOf/.test(props); - iteratesOwnLast = props[0] != 'x'; - }(1)); - - /** Detect if an `arguments` object's [[Class]] is unresolvable (Firefox < 4, IE < 9) */ - var noArgsClass = !isArguments(arguments); - - /** Detect if `Array#slice` cannot be used to convert strings to arrays (Opera < 10.52) */ - var noArraySliceOnStrings = slice.call('x')[0] != 'x'; - - /** - * Detect lack of support for accessing string characters by index: - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - */ - var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a node's [[Class]] is unresolvable (IE < 9) - * and that the JS engine won't error when attempting to coerce an object to - * a string without a `toString` property value of `typeof` "function". - */ - try { - var noNodeClass = ({ 'toString': 0 } + '', toString.call(window.document || 0) == objectClass); - } catch(e) { } - - /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */ - var isBindFast = nativeBind && /\n|Opera/.test(nativeBind + toString.call(window.opera)); - - /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */ - var isKeysFast = nativeKeys && /^.+$|true/.test(nativeKeys + !!window.attachEvent); - - /** - * Detect if sourceURL syntax is usable without erroring: - * - * The JS engine in Adobe products, like InDesign, will throw a syntax error - * when it encounters a single line comment beginning with the `@` symbol. - * - * The JS engine in Narwhal will generate the function `function anonymous(){//}` - * and throw a syntax error. - * - * Avoid comments beginning `@` symbols in IE because they are part of its - * non-standard conditional compilation support. - * http://msdn.microsoft.com/en-us/library/121hztk3(v=vs.94).aspx - */ - try { - var useSourceURL = (Function('//@')(), !window.attachEvent); - } catch(e) { } - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[argsClass] = cloneableClasses[funcClass] = false; - cloneableClasses[arrayClass] = cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = cloneableClasses[regexpClass] = - cloneableClasses[stringClass] = true; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The `lodash` function. - * - * @name _ - * @constructor - * @category Chaining - * @param {Mixed} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - */ - function lodash(value) { - // exit early if already wrapped - if (value && value.__wrapped__) { - return value; - } - // allow invoking `lodash` without the `new` operator - if (!(this instanceof lodash)) { - return new lodash(value); - } - this.__wrapped__ = value; - } - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @static - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @static - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @static - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @static - * @memberOf _.templateSettings - * @type String - */ - 'variable': '' - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Obect} data The data object used to populate the text. - * @returns {String} Returns the interpolated text. - */ - var iteratorTemplate = template( - // conditional strict mode - '<% if (obj.useStrict) { %>\'use strict\';\n<% } %>' + - - // the `iteratee` may be reassigned by the `top` snippet - 'var index, value, iteratee = <%= firstArg %>, ' + - // assign the `result` variable an initial value - 'result = <%= firstArg %>;\n' + - // exit early if the first argument is falsey - 'if (!<%= firstArg %>) return result;\n' + - // add code before the iteration branches - '<%= top %>;\n' + - - // array-like iteration: - '<% if (arrayLoop) { %>' + - 'var length = iteratee.length; index = -1;\n' + - 'if (typeof length == \'number\') {' + - - // add support for accessing string characters by index if needed - ' <% if (noCharByIndex) { %>\n' + - ' if (isString(iteratee)) {\n' + - ' iteratee = iteratee.split(\'\')\n' + - ' }' + - ' <% } %>\n' + - - // iterate over the array-like value - ' while (++index < length) {\n' + - ' value = iteratee[index];\n' + - ' <%= arrayLoop %>\n' + - ' }\n' + - '}\n' + - 'else {' + - - // object iteration: - // add support for iterating over `arguments` objects if needed - ' <% } else if (noArgsEnum) { %>\n' + - ' var length = iteratee.length; index = -1;\n' + - ' if (length && isArguments(iteratee)) {\n' + - ' while (++index < length) {\n' + - ' value = iteratee[index += \'\'];\n' + - ' <%= objectLoop %>\n' + - ' }\n' + - ' } else {' + - ' <% } %>' + - - // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - // (if the prototype or a property on the prototype has been set) - // incorrectly sets a function's `prototype` property [[Enumerable]] - // value to `true`. Because of this Lo-Dash standardizes on skipping - // the the `prototype` property of functions regardless of its - // [[Enumerable]] value. - ' <% if (!hasDontEnumBug) { %>\n' + - ' var skipProto = typeof iteratee == \'function\' && \n' + - ' propertyIsEnumerable.call(iteratee, \'prototype\');\n' + - ' <% } %>' + - - // iterate own properties using `Object.keys` if it's fast - ' <% if (isKeysFast && useHas) { %>\n' + - ' var ownIndex = -1,\n' + - ' ownProps = objectTypes[typeof iteratee] ? nativeKeys(iteratee) : [],\n' + - ' length = ownProps.length;\n\n' + - ' while (++ownIndex < length) {\n' + - ' index = ownProps[ownIndex];\n' + - ' <% if (!hasDontEnumBug) { %>if (!(skipProto && index == \'prototype\')) {\n <% } %>' + - ' value = iteratee[index];\n' + - ' <%= objectLoop %>\n' + - ' <% if (!hasDontEnumBug) { %>}\n<% } %>' + - ' }' + - - // else using a for-in loop - ' <% } else { %>\n' + - ' for (index in iteratee) {<%' + - ' if (!hasDontEnumBug || useHas) { %>\n if (<%' + - ' if (!hasDontEnumBug) { %>!(skipProto && index == \'prototype\')<% }' + - ' if (!hasDontEnumBug && useHas) { %> && <% }' + - ' if (useHas) { %>hasOwnProperty.call(iteratee, index)<% }' + - ' %>) {' + - ' <% } %>\n' + - ' value = iteratee[index];\n' + - ' <%= objectLoop %>;' + - ' <% if (!hasDontEnumBug || useHas) { %>\n }<% } %>\n' + - ' }' + - ' <% } %>' + - - // Because IE < 9 can't set the `[[Enumerable]]` attribute of an - // existing property and the `constructor` property of a prototype - // defaults to non-enumerable, Lo-Dash skips the `constructor` - // property when it infers it's iterating over a `prototype` object. - ' <% if (hasDontEnumBug) { %>\n\n' + - ' var ctor = iteratee.constructor;\n' + - ' <% for (var k = 0; k < 7; k++) { %>\n' + - ' index = \'<%= shadowed[k] %>\';\n' + - ' if (<%' + - ' if (shadowed[k] == \'constructor\') {' + - ' %>!(ctor && ctor.prototype === iteratee) && <%' + - ' } %>hasOwnProperty.call(iteratee, index)) {\n' + - ' value = iteratee[index];\n' + - ' <%= objectLoop %>\n' + - ' }' + - ' <% } %>' + - ' <% } %>' + - ' <% if (arrayLoop || noArgsEnum) { %>\n}<% } %>\n' + - - // add code to the bottom of the iteration function - '<%= bottom %>;\n' + - // finally, return the `result` - 'return result' - ); - - /** - * Reusable iterator options shared by `forEach`, `forIn`, and `forOwn`. - */ - var forEachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': 'callback = createCallback(callback, thisArg)', - 'arrayLoop': 'if (callback(value, index, collection) === false) return result', - 'objectLoop': 'if (callback(value, index, collection) === false) return result' - }; - - /** Reusable iterator options for `defaults`, and `extend` */ - var extendIteratorOptions = { - 'useHas': false, - 'args': 'object', - 'top': - 'for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {\n' + - ' if (iteratee = arguments[argsIndex]) {', - 'objectLoop': 'result[index] = value', - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'arrayLoop': null - }; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function optimized to search large arrays for a given `value`, - * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`. - * - * @private - * @param {Array} array The array to search. - * @param {Mixed} value The value to search for. - * @param {Number} [fromIndex=0] The index to search from. - * @param {Number} [largeSize=30] The length at which an array is considered large. - * @returns {Boolean} Returns `true` if `value` is found, else `false`. - */ - function cachedContains(array, fromIndex, largeSize) { - fromIndex || (fromIndex = 0); - - var length = array.length, - isLarge = (length - fromIndex) >= (largeSize || largeArraySize); - - if (isLarge) { - var cache = {}, - index = fromIndex - 1; - - while (++index < length) { - // manually coerce `value` to a string because `hasOwnProperty`, in some - // older versions of Firefox, coerces objects incorrectly - var key = array[index] + ''; - (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]); - } - } - return function(value) { - if (isLarge) { - var key = value + ''; - return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1; - } - return indexOf(array, value, fromIndex) > -1; - } - } - - /** - * Used by `_.max` and `_.min` as the default `callback` when a given - * `collection` is a string value. - * - * @private - * @param {String} value The character to inspect. - * @returns {Number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` values, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {Number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ai = a.index, - bi = b.index; - - a = a.criteria; - b = b.criteria; - - // ensure a stable sort in V8 and other engines - // http://code.google.com/p/v8/issues/detail?id=90 - if (a !== b) { - if (a > b || a === undefined) { - return 1; - } - if (a < b || b === undefined) { - return -1; - } - } - return ai < bi ? -1 : 1; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any `partailArgs` to the arguments passed - * to the bound function. - * - * @private - * @param {Function|String} func The function to bind or the method name. - * @param {Mixed} [thisArg] The `this` binding of `func`. - * @param {Array} partialArgs An array of arguments to be partially applied. - * @returns {Function} Returns the new bound function. - */ - function createBound(func, thisArg, partialArgs) { - var isFunc = isFunction(func), - isPartial = !partialArgs, - methodName = func; - - // juggle arguments - if (isPartial) { - partialArgs = thisArg; - } - - function bound() { - // `Function#bind` spec - // http://es5.github.com/#x15.3.4.5 - var args = arguments, - thisBinding = isPartial ? this : thisArg; - - if (!isFunc) { - func = thisArg[methodName]; - } - if (partialArgs.length) { - args = args.length - ? partialArgs.concat(slice.call(args)) - : partialArgs; - } - if (this instanceof bound) { - // get `func` instance if `bound` is invoked in a `new` expression - noop.prototype = func.prototype; - thisBinding = new noop; - - // mimic the constructor's `return` behavior - // http://es5.github.com/#x13.2.2 - var result = func.apply(thisBinding, args); - return isObject(result) - ? result - : thisBinding - } - return func.apply(thisBinding, args); - } - return bound; - } - - /** - * Produces an iteration callback bound to an optional `thisArg`. If `func` is - * a property name, the callback will return the property value for a given element. - * - * @private - * @param {Function|String} [func=identity|property] The function called per - * iteration or property name to query. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Function} Returns a callback function. - */ - function createCallback(func, thisArg) { - if (!func) { - return identity; - } - if (typeof func != 'function') { - return function(object) { - return object[func]; - }; - } - if (thisArg !== undefined) { - return function(value, index, object) { - return func.call(thisArg, value, index, object); - }; - } - return func; - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {Object} [options1, options2, ...] The compile options object(s). - * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop. - * args - A string of comma separated arguments the iteration function will accept. - * top - A string of code to execute before the iteration branches. - * arrayLoop - A string of code to execute in the array loop. - * objectLoop - A string of code to execute in the object loop. - * bottom - A string of code to execute after the iteration branches. - * - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - var data = { - 'arrayLoop': '', - 'bottom': '', - 'hasDontEnumBug': hasDontEnumBug, - 'isKeysFast': isKeysFast, - 'objectLoop': '', - 'noArgsEnum': noArgsEnum, - 'noCharByIndex': noCharByIndex, - 'shadowed': shadowed, - 'top': '', - 'useHas': true - }; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - data[key] = object[key]; - } - } - var args = data.args; - data.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'createCallback, hasOwnProperty, isArguments, isString, objectTypes, ' + - 'nativeKeys, propertyIsEnumerable', - 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}' - ); - // return the compiled function - return factory( - createCallback, hasOwnProperty, isArguments, isString, objectTypes, - nativeKeys, propertyIsEnumerable - ); - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {String} match The matched character to escape. - * @returns {String} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {String} match The matched character to escape. - * @returns {String} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * A no-operation function. - * - * @private - */ - function noop() { - // no operation performed - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {String} match The matched character to unescape. - * @returns {String} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return toString.call(value) == argsClass; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (noArgsClass) { - isArguments = function(value) { - return value ? hasOwnProperty.call(value, 'callee') : false; - }; - } - - /** - * Iterates over `object`'s own and inherited enumerable properties, executing - * the `callback` for each property. The `callback` is bound to `thisArg` and - * invoked with three arguments; (value, key, object). Callbacks may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Dog(name) { - * this.name = name; - * } - * - * Dog.prototype.bark = function() { - * alert('Woof, woof!'); - * }; - * - * _.forIn(new Dog('Dagny'), function(value, key) { - * alert(key); - * }); - * // => alerts 'name' and 'bark' (order is not guaranteed) - */ - var forIn = createIterator(forEachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * Iterates over `object`'s own enumerable properties, executing the `callback` - * for each property. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by explicitly - * returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * alert(key); - * }); - * // => alerts '0', '1', and 'length' (order is not guaranteed) - */ - var forOwn = createIterator(forEachIteratorOptions, forOwnIteratorOptions); - - /** - * A fallback implementation of `isPlainObject` that checks if a given `value` - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - // avoid non-objects and false positives for `arguments` objects - var result = false; - if (!(value && typeof value == 'object') || isArguments(value)) { - return result; - } - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings. - // Also check that the constructor is `Object` (i.e. `Object instanceof Object`) - var ctor = value.constructor; - if ((!noNodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) && - (!isFunction(ctor) || ctor instanceof ctor)) { - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (iteratesOwnLast) { - forIn(value, function(value, key, object) { - result = !hasOwnProperty.call(object, key); - return false; - }); - return result === false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return result === false || hasOwnProperty.call(value, result); - } - return result; - } - - /** - * A fallback implementation of `Object.keys` that produces an array of the - * given object's own enumerable property names. - * - * @private - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names. - */ - function shimKeys(object) { - var result = []; - forOwn(object, function(value, key) { - result.push(key); - }); - return result; - } - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a clone of `value`. If `deep` is `true`, all nested objects will - * also be cloned otherwise they will be assigned by reference. Functions, DOM - * nodes, `arguments` objects, and objects created by constructors other than - * `Object` are **not** cloned. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to clone. - * @param {Boolean} deep A flag to indicate a deep clone. - * @param- {Object} [guard] Internally used to allow this method to work with - * others like `_.map` without using their callback `index` argument for `deep`. - * @param- {Array} [stackA=[]] Internally used to track traversed source objects. - * @param- {Array} [stackB=[]] Internally used to associate clones with their - * source counterparts. - * @returns {Mixed} Returns the cloned `value`. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 }, - * { 'name': 'curly', 'age': 60 } - * ]; - * - * _.clone({ 'name': 'moe' }); - * // => { 'name': 'moe' } - * - * var shallow = _.clone(stooges); - * shallow[0] === stooges[0]; - * // => true - * - * var deep = _.clone(stooges, true); - * shallow[0] === stooges[0]; - * // => false - */ - function clone(value, deep, guard, stackA, stackB) { - if (value == null) { - return value; - } - if (guard) { - deep = false; - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - // don't clone `arguments` objects, functions, or non-object Objects - var className = toString.call(value); - if (!cloneableClasses[className] || (noArgsClass && isArguments(value))) { - return value; - } - var isArr = className == arrayClass; - isObj = isArr || (className == objectClass ? isPlainObject(value) : isObj); - } - // shallow clone - if (!isObj || !deep) { - // don't clone functions - return isObj - ? (isArr ? slice.call(value) : extend({}, value)) - : value; - } - - var ctor = value.constructor; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - return ctor(value.source, reFlags.exec(value)); - } - // check for circular references and return corresponding clone - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - // init cloned object - var result = isArr ? ctor(value.length) : {}; - - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? forEach : forOwn)(value, function(objValue, key) { - result[key] = clone(objValue, deep, null, stackA, stackB); - }); - - return result; - } - - /** - * Assigns enumerable properties of the default object(s) to the `destination` - * object for all `destination` properties that resolve to `null`/`undefined`. - * Once a property is set, additional defaults of the same property will be - * ignored. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {Object} [default1, default2, ...] The default objects. - * @returns {Object} Returns the destination object. - * @example - * - * var iceCream = { 'flavor': 'chocolate' }; - * _.defaults(iceCream, { 'flavor': 'vanilla', 'sprinkles': 'rainbow' }); - * // => { 'flavor': 'chocolate', 'sprinkles': 'rainbow' } - */ - var defaults = createIterator(extendIteratorOptions, { - 'objectLoop': 'if (result[index] == null) ' + extendIteratorOptions.objectLoop - }); - - /** - * Assigns enumerable properties of the source object(s) to the `destination` - * object. Subsequent sources will overwrite propery assignments of previous - * sources. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {Object} [source1, source2, ...] The source objects. - * @returns {Object} Returns the destination object. - * @example - * - * _.extend({ 'name': 'moe' }, { 'age': 40 }); - * // => { 'name': 'moe', 'age': 40 } - */ - var extend = createIterator(extendIteratorOptions); - - /** - * Creates a sorted array of all enumerable properties, own and inherited, - * of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified object `property` exists and is a direct property, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to check. - * @param {String} property The property to check for. - * @returns {Boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, property) { - return object ? hasOwnProperty.call(object, property) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'Moe', 'second': 'Larry', 'third': 'Curly' }); - * // => { 'Moe': 'first', 'Larry': 'second', 'Curly': 'third' } (order is not guaranteed) - */ - function invert(object) { - var result = {}; - forOwn(object, function(value, key) { - result[value] = key; - }); - return result; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return toString.call(value) == arrayClass; - }; - - /** - * Checks if `value` is a boolean (`true` or `false`) value. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || toString.call(value) == boolClass; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return toString.call(value) == dateClass; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value ? value.nodeType === 1 : false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|String} value The value to inspect. - * @returns {Boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - className == argsClass || (noArgsClass && isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} a The value to compare. - * @param {Mixed} b The other value to compare. - * @param- {Object} [stackA=[]] Internally used track traversed `a` objects. - * @param- {Object} [stackB=[]] Internally used track traversed `b` objects. - * @returns {Boolean} Returns `true` if the values are equvalent, else `false`. - * @example - * - * var moe = { 'name': 'moe', 'luckyNumbers': [13, 27, 34] }; - * var clone = { 'name': 'moe', 'luckyNumbers': [13, 27, 34] }; - * - * moe == clone; - * // => false - * - * _.isEqual(moe, clone); - * // => true - */ - function isEqual(a, b, stackA, stackB) { - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - // a strict comparison is necessary because `null == undefined` - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a); - if (className != toString.call(b)) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return a != +a - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.com/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == b + ''; - } - // exit early, in older browsers, if `a` is array-like but not `b` - var isArr = className == arrayClass || className == argsClass; - if (noArgsClass && !isArr && (isArr = isArguments(a)) && !isArguments(b)) { - return false; - } - if (!isArr) { - // unwrap any `lodash` wrapped values - if (a.__wrapped__ || b.__wrapped__) { - return isEqual(a.__wrapped__ || a, b.__wrapped__ || b); - } - // exit for functions and DOM nodes - if (className != objectClass || (noNodeClass && ( - (typeof a.toString != 'function' && typeof (a + '') == 'string') || - (typeof b.toString != 'function' && typeof (b + '') == 'string')))) { - return false; - } - var ctorA = a.constructor, - ctorB = b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && !( - isFunction(ctorA) && ctorA instanceof ctorA && - isFunction(ctorB) && ctorB instanceof ctorB - )) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3) - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - - var index = -1, - result = true, - size = 0; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - size = a.length; - result = size == b.length; - - if (result) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - if (!(result = isEqual(a[size], b[size], stackA, stackB))) { - break; - } - } - } - return result; - } - // deep compare objects - for (var key in a) { - if (hasOwnProperty.call(a, key)) { - // count the number of properties. - size++; - // deep compare each property value. - if (!(hasOwnProperty.call(b, key) && isEqual(a[key], b[key], stackA, stackB))) { - return false; - } - } - } - // ensure both objects have the same number of properties - for (key in b) { - // The JS engine in Adobe products, like InDesign, has a bug that causes - // `!size--` to throw an error so it must be wrapped in parentheses. - // https://github.com/documentcloud/underscore/issues/355 - if (hasOwnProperty.call(b, key) && !(size--)) { - // `size` will be `-1` if `b` has more properties than `a` - return false; - } - } - // handle JScript [[DontEnum]] bug - if (hasDontEnumBug) { - while (++index < 7) { - key = shadowed[index]; - if (hasOwnProperty.call(a, key) && - !(hasOwnProperty.call(b, key) && isEqual(a[key], b[key], stackA, stackB))) { - return false; - } - } - } - return true; - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite`, which will return true for - * booleans and empty strings. See http://es5.github.com/#x15.1.2.5. - * - * @deprecated - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a finite number, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.com/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return value ? objectTypes[typeof value] : false; - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN`, which will return true for - * `undefined` and other values. See http://es5.github.com/#x15.1.2.4. - * - * @deprecated - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return toString.call(value) == numberClass && value != +value - } - - /** - * Checks if `value` is `null`. - * - * @deprecated - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return toString.call(value) == numberClass; - } - - /** - * Checks if a given `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Stooge(name, age) { - * this.name = name; - * this.age = age; - * } - * - * _.isPlainObject(new Stooge('moe', 40)); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'name': 'moe', 'age': 40 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && typeof value == 'object')) { - return false; - } - var valueOf = value.valueOf, - objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value)) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/moe/); - * // => true - */ - function isRegExp(value) { - return toString.call(value) == regexpClass; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('moe'); - * // => true - */ - function isString(value) { - return toString.call(value) == stringClass; - } - - /** - * Checks if `value` is `undefined`. - * - * @deprecated - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * Creates an array composed of the own enumerable property names of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (order is not guaranteed) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - // avoid iterating over the `prototype` property - return typeof object == 'function' && propertyIsEnumerable.call(object, 'prototype') - ? shimKeys(object) - : (isObject(object) ? nativeKeys(object) : []); - }; - - /** - * Merges enumerable properties of the source object(s) into the `destination` - * object. Subsequent sources will overwrite propery assignments of previous - * sources. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {Object} [source1, source2, ...] The source objects. - * @param- {Object} [indicator] Internally used to indicate that the `stack` - * argument is an array of traversed objects instead of another source object. - * @param- {Array} [stackA=[]] Internally used to track traversed source objects. - * @param- {Array} [stackB=[]] Internally used to associate values with their - * source counterparts. - * @returns {Object} Returns the destination object. - * @example - * - * var stooges = [ - * { 'name': 'moe' }, - * { 'name': 'larry' } - * ]; - * - * var ages = [ - * { 'age': 40 }, - * { 'age': 50 } - * ]; - * - * _.merge(stooges, ages); - * // => [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] - */ - function merge(object, source, indicator) { - var args = arguments, - index = 0, - length = 2, - stackA = args[3], - stackB = args[4]; - - if (indicator !== objectRef) { - stackA = []; - stackB = []; - length = args.length; - } - while (++index < length) { - forOwn(args[index], function(source, key) { - var found, isArr, value; - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - found = stackA[stackLength] == source; - if (found) { - break; - } - } - if (found) { - object[key] = stackB[stackLength]; - } - else { - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value = (value = object[key], isArr) - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}) - ); - // recursively merge objects and arrays (susceptible to call stack limits) - object[key] = merge(value, source, objectRef, stackA, stackB); - } - } else if (source != null) { - object[key] = source; - } - }); - } - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If `callback` is passed, it will be executed for each property - * in the `object`, omitting the properties `callback` returns truthy for. The - * `callback` is bound to `thisArg` and invoked with three arguments; (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit - * or the function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'userid'); - * // => { 'name': 'moe', 'age': 40 } - * - * _.omit({ 'name': 'moe', '_hint': 'knucklehead', '_seed': '96c4eb' }, function(value, key) { - * return key.charAt(0) == '_'; - * }); - * // => { 'name': 'moe' } - */ - function omit(object, callback, thisArg) { - var isFunc = typeof callback == 'function', - result = {}; - - if (isFunc) { - callback = createCallback(callback, thisArg); - } else { - var props = concat.apply(arrayRef, arguments); - } - forIn(object, function(value, key, object) { - if (isFunc - ? !callback(value, key, object) - : indexOf(props, key, 1) < 0 - ) { - result[key] = value; - } - }); - return result; - } - - /** - * Creates a two dimensional array of the given object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'moe': 30, 'larry': 40, 'curly': 50 }); - * // => [['moe', 30], ['larry', 40], ['curly', 50]] (order is not guaranteed) - */ - function pairs(object) { - var result = []; - forOwn(object, function(value, key) { - result.push([key, value]); - }); - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If `callback` is passed, it will be executed for each property - * in the `object`, picking the properties `callback` returns truthy for. The - * `callback` is bound to `thisArg` and invoked with three arguments; (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|String} callback|[prop1, prop2, ...] The properties to pick - * or the function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'moe', 'age': 40, 'userid': 'moe1' }, 'name', 'age'); - * // => { 'name': 'moe', 'age': 40 } - * - * _.pick({ 'name': 'moe', '_hint': 'knucklehead', '_seed': '96c4eb' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'moe' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = 0, - props = concat.apply(arrayRef, arguments), - length = props.length; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = createCallback(callback, thisArg); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] - */ - function values(object) { - var result = []; - forOwn(object, function(value) { - result.push(value); - }); - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if a given `target` element is present in a `collection` using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Mixed} target The value to check for. - * @param {Number} [fromIndex=0] The index to search from. - * @returns {Boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'moe', 'age': 40 }, 'moe'); - * // => true - * - * _.contains('curly', 'ur'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - length = collection ? collection.length : 0; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (typeof length == 'number') { - return (isString(collection) - ? collection.indexOf(target, fromIndex) - : indexOf(collection, target, fromIndex) - ) > -1; - } - return some(collection, function(value) { - return ++index >= fromIndex && value === target; - }); - } - - /** - * Creates an object composed of keys returned from running each element of - * `collection` through a `callback`. The corresponding value of each key is - * the number of times the key was returned by `callback`. The `callback` is - * bound to `thisArg` and invoked with three arguments; (value, index|key, collection). - * The `callback` argument may also be the name of a property to count by (e.g. 'length'). - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|String} callback|property The function called per iteration - * or property name to count by. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - function countBy(collection, callback, thisArg) { - var result = {}; - callback = createCallback(callback, thisArg); - forEach(collection, function(value, key, collection) { - key = callback(value, key, collection); - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - return result; - } - - /** - * Checks if the `callback` returns a truthy value for **all** elements of a - * `collection`. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Boolean} Returns `true` if all elements pass the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = createCallback(callback, thisArg); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - forEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Examines each element in a `collection`, returning an array of all elements - * the `callback` returns truthy for. The `callback` is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = createCallback(callback, thisArg); - forEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * Examines each element in a `collection`, returning the first one the `callback` - * returns truthy for. The function returns as soon as it finds an acceptable - * element, and does not iterate over the entire `collection`. The `callback` is - * bound to `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * @static - * @memberOf _ - * @alias detect - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} callback The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the element that passed the callback check, - * else `undefined`. - * @example - * - * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => 2 - */ - function find(collection, callback, thisArg) { - var result; - callback = createCallback(callback, thisArg); - forEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over a `collection`, executing the `callback` for each element in - * the `collection`. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). Callbacks may exit iteration early - * by explicitly returning `false`. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} callback The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|String} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(alert).join(','); - * // => alerts each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert); - * // => alerts each number (order is not guaranteed) - */ - var forEach = createIterator(forEachIteratorOptions); - - /** - * Creates an object composed of keys returned from running each element of - * `collection` through a `callback`. The corresponding value of each key is an - * array of elements passed to `callback` that returned the key. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). - * The `callback` argument may also be the name of a property to group by (e.g. 'length'). - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|String} callback|property The function called per iteration - * or property name to group by. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - function groupBy(collection, callback, thisArg) { - var result = {}; - callback = createCallback(callback, thisArg); - forEach(collection, function(value, key, collection) { - key = callback(value, key, collection); - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - return result; - } - - /** - * Invokes the method named by `methodName` on each element in the `collection`, - * returning an array of the results of each invoked method. Additional arguments - * will be passed to each invoked method. If `methodName` is a function it will - * be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|String} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice.call(arguments, 2), - isFunc = typeof methodName == 'function', - result = []; - - forEach(collection, function(value) { - result.push((isFunc ? methodName : value[methodName]).apply(value, args)); - }); - return result; - } - - /** - * Creates an array of values by running each element in the `collection` - * through a `callback`. The `callback` is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (order is not guaranteed) - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = createCallback(callback, thisArg); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - forEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of an `array`. If `callback` is passed, - * it will be executed for each value in the `array` to generate the - * criterion by which the value is ranked. The `callback` is bound to - * `thisArg` and invoked with three arguments; (value, index, collection). - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the maximum value. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 }, - * { 'name': 'curly', 'age': 60 } - * ]; - * - * _.max(stooges, function(stooge) { return stooge.age; }); - * // => { 'name': 'curly', 'age': 60 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - index = -1, - length = collection ? collection.length : 0, - result = computed; - - if (callback || !isArray(collection)) { - callback = !callback && isString(collection) - ? charAtCallback - : createCallback(callback, thisArg); - - forEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } else { - while (++index < length) { - if (collection[index] > result) { - result = collection[index]; - } - } - } - return result; - } - - /** - * Retrieves the minimum value of an `array`. If `callback` is passed, - * it will be executed for each value in the `array` to generate the - * criterion by which the value is ranked. The `callback` is bound to `thisArg` - * and invoked with three arguments; (value, index, collection). - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the minimum value. - * @example - * - * _.min([10, 5, 100, 2, 1000]); - * // => 2 - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - index = -1, - length = collection ? collection.length : 0, - result = computed; - - if (callback || !isArray(collection)) { - callback = !callback && isString(collection) - ? charAtCallback - : createCallback(callback, thisArg); - - forEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } else { - while (++index < length) { - if (collection[index] < result) { - result = collection[index]; - } - } - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in - * the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {String} property The property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 }, - * { 'name': 'curly', 'age': 60 } - * ]; - * - * _.pluck(stooges, 'name'); - * // => ['moe', 'larry', 'curly'] - */ - function pluck(collection, property) { - var result = []; - forEach(collection, function(value) { - result.push(value[property]); - }); - return result; - } - - /** - * Boils down a `collection` to a single value. The initial state of the - * reduction is `accumulator` and each successive step of it should be returned - * by the `callback`. The `callback` is bound to `thisArg` and invoked with 4 - * arguments; for arrays they are (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} callback The function called per iteration. - * @param {Mixed} [accumulator] Initial value of the accumulator. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; }); - * // => 6 - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = createCallback(callback, thisArg); - forEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - return accumulator; - } - - /** - * The right-associative version of `_.reduce`. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} callback The function called per iteration. - * @param {Mixed} [accumulator] Initial value of the accumulator. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var iteratee = collection, - length = collection ? collection.length : 0, - noaccum = arguments.length < 3; - - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (noCharByIndex && isString(collection)) { - iteratee = collection.split(''); - } - forEach(collection, function(value, index, collection) { - index = props ? props[--length] : --length; - accumulator = noaccum - ? (noaccum = false, iteratee[index]) - : callback.call(thisArg, accumulator, iteratee[index], index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter`, this method returns the values of a - * `collection` that `callback` does **not** return truthy for. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that did **not** pass the - * callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - */ - function reject(collection, callback, thisArg) { - callback = createCallback(callback, thisArg); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Creates an array of shuffled `array` values, using a version of the - * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - result = Array(collection ? collection.length : 0); - - forEach(collection, function(value) { - var rand = floor(nativeRandom() * (++index + 1)); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to inspect. - * @returns {Number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('curly'); - * // => 5 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the `callback` returns a truthy value for **any** element of a - * `collection`. The function returns as soon as it finds passing value, and - * does not iterate over the entire `collection`. The `callback` is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Boolean} Returns `true` if any element passes the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false]); - * // => true - */ - function some(collection, callback, thisArg) { - var result; - callback = createCallback(callback, thisArg); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (result = callback(collection[index], index, collection)) { - break; - } - } - } else { - forEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array, stable sorted in ascending order by the results of - * running each element of `collection` through a `callback`. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). - * The `callback` argument may also be the name of a property to sort by (e.g. 'length'). - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|String} callback|property The function called per iteration - * or property name to sort by. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * _.sortBy(['larry', 'brendan', 'moe'], 'length'); - * // => ['moe', 'larry', 'brendan'] - */ - function sortBy(collection, callback, thisArg) { - var result = []; - callback = createCallback(callback, thisArg); - forEach(collection, function(value, index, collection) { - result.push({ - 'criteria': callback(value, index, collection), - 'index': index, - 'value': value - }); - }); - - var length = result.length; - result.sort(compareAscending); - while (length--) { - result[length] = result[length].value; - } - return result; - } - - /** - * Converts the `collection`, to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (noArraySliceOnStrings ? isString(collection) : typeof collection == 'string') - ? collection.split('') - : slice.call(collection); - } - return values(collection); - } - - /** - * Examines each element in a `collection`, returning an array of all elements - * that contain the given `properties`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Object} properties The object of property values to filter by. - * @returns {Array} Returns a new array of elements that contain the given `properties`. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 }, - * { 'name': 'curly', 'age': 60 } - * ]; - * - * _.where(stooges, { 'age': 40 }); - * // => [{ 'name': 'moe', 'age': 40 }] - */ - function where(collection, properties) { - var props = []; - forIn(properties, function(value, prop) { - props.push(prop); - }); - return filter(collection, function(object) { - var length = props.length; - while (length--) { - var result = object[props[length]] === properties[props[length]]; - if (!result) { - break; - } - } - return !!result; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values of `array` removed. The values - * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new filtered array. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array of `array` elements not present in the other arrays - * using strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {Array} [array1, array2, ...] Arrays to check. - * @returns {Array} Returns a new array of `array` elements not present in the - * other arrays. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - var index = -1, - length = array ? array.length : 0, - flattened = concat.apply(arrayRef, arguments), - contains = cachedContains(flattened, length), - result = []; - - while (++index < length) { - var value = array[index]; - if (!contains(value)) { - result.push(value); - } - } - return result; - } - - /** - * Gets the first element of the `array`. Pass `n` to return the first `n` - * elements of the `array`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Number} [n] The number of elements to return. - * @param- {Object} [guard] Internally used to allow this method to work with - * others like `_.map` without using their callback `index` argument for `n`. - * @returns {Mixed} Returns the first element or an array of the first `n` - * elements of `array`. - * @example - * - * _.first([5, 4, 3, 2, 1]); - * // => 5 - */ - function first(array, n, guard) { - if (array) { - return (n == null || guard) ? array[0] : slice.call(array, 0, n); - } - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `shallow` is - * truthy, `array` will only be flattened a single level. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @param {Boolean} shallow A flag to indicate only flattening a single level. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - */ - function flatten(array, shallow) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - // recursively flatten arrays (susceptible to call stack limits) - if (isArray(value)) { - push.apply(result, shallow ? value : flatten(value)); - } else { - result.push(value); - } - } - return result; - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the `array` is already - * sorted, passing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Mixed} value The value to search for. - * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to - * perform a binary search on a sorted `array`. - * @returns {Number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - var index = -1, - length = array ? array.length : 0; - - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1; - } else if (fromIndex) { - index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Gets all but the last element of `array`. Pass `n` to exclude the last `n` - * elements from the result. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Number} [n=1] The number of elements to exclude. - * @param- {Object} [guard] Internally used to allow this method to work with - * others like `_.map` without using their callback `index` argument for `n`. - * @returns {Array} Returns all but the last element or `n` elements of `array`. - * @example - * - * _.initial([3, 2, 1]); - * // => [3, 2] - */ - function initial(array, n, guard) { - return array - ? slice.call(array, 0, -((n == null || guard) ? 1 : n)) - : []; - } - - /** - * Computes the intersection of all the passed-in arrays using strict equality - * for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} [array1, array2, ...] Arrays to process. - * @returns {Array} Returns a new array of unique elements, in order, that are - * present in **all** of the arrays. - * @example - * - * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); - * // => [1, 2] - */ - function intersection(array) { - var args = arguments, - argsLength = args.length, - cache = {}, - result = []; - - forEach(array, function(value) { - if (indexOf(result, value) < 0) { - var length = argsLength; - while (--length) { - if (!(cache[length] || (cache[length] = cachedContains(args[length])))(value)) { - return; - } - } - result.push(value); - } - }); - return result; - } - - /** - * Gets the last element of the `array`. Pass `n` to return the last `n` - * elements of the `array`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Number} [n] The number of elements to return. - * @param- {Object} [guard] Internally used to allow this method to work with - * others like `_.map` without using their callback `index` argument for `n`. - * @returns {Mixed} Returns the last element or an array of the last `n` - * elements of `array`. - * @example - * - * _.last([3, 2, 1]); - * // => 1 - */ - function last(array, n, guard) { - if (array) { - var length = array.length; - return (n == null || guard) ? array[length - 1] : slice.call(array, -n || length); - } - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Mixed} value The value to search for. - * @param {Number} [fromIndex=array.length-1] The index to search from. - * @returns {Number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Pass either - * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or - * two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.object(['moe', 'larry', 'curly'], [30, 40, 50]); - * // => { 'moe': 30, 'larry': 40, 'curly': 50 } - */ - function object(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else { - result[key[0]] = key[1]; - } - } - return result; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `stop`. This method is a port of Python's - * `range()` function. See http://docs.python.org/library/functions.html#range. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Number} [start=0] The start of the range. - * @param {Number} end The end of the range. - * @param {Number} [step=1] The value to increment or descrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(10); - * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - * - * _.range(1, 11); - * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - * - * _.range(0, 30, 5); - * // => [0, 5, 10, 15, 20, 25] - * - * _.range(0, -10, -1); - * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = +step || 1; - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so V8 will avoid the slower "dictionary" mode - // http://www.youtube.com/watch?v=XAqIpGU8ZZk#t=16m27s - var index = -1, - length = nativeMax(0, ceil((end - start) / step)), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * The opposite of `_.initial`, this method gets all but the first value of - * `array`. Pass `n` to exclude the first `n` values from the result. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Number} [n=1] The number of elements to exclude. - * @param- {Object} [guard] Internally used to allow this method to work with - * others like `_.map` without using their callback `index` argument for `n`. - * @returns {Array} Returns all but the first value or `n` values of `array`. - * @example - * - * _.rest([3, 2, 1]); - * // => [2, 1] - */ - function rest(array, n, guard) { - return array - ? slice.call(array, (n == null || guard) ? 1 : n) - : []; - } - - /** - * Uses a binary search to determine the smallest index at which the `value` - * should be inserted into `array` in order to maintain the sort order of the - * sorted `array`. If `callback` is passed, it will be executed for `value` and - * each element in `array` to compute their sort ranking. The `callback` is - * bound to `thisArg` and invoked with one argument; (value). The `callback` - * argument may also be the name of a property to order by. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to iterate over. - * @param {Mixed} value The value to evaluate. - * @param {Function|String} [callback=identity|property] The function called - * per iteration or property name to order by. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Number} Returns the index at which the value should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better engine inlining - callback = callback ? createCallback(callback, thisArg) : identity; - value = callback(value); - while (low < high) { - var mid = (low + high) >>> 1; - callback(array[mid]) < value - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Computes the union of the passed-in arrays using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} [array1, array2, ...] Arrays to process. - * @returns {Array} Returns a new array of unique values, in order, that are - * present in one or more of the arrays. - * @example - * - * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); - * // => [1, 2, 3, 101, 10] - */ - function union() { - return uniq(concat.apply(arrayRef, arguments)); - } - - /** - * Creates a duplicate-value-free version of the `array` using strict equality - * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true` - * for `isSorted` will run a faster algorithm. If `callback` is passed, each - * element of `array` is passed through a callback` before uniqueness is computed. - * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array). - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); }); - * // => [1, 2, 3] - * - * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2, 3] - */ - function uniq(array, isSorted, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = [], - seen = result; - - // juggle arguments - if (typeof isSorted == 'function') { - thisArg = callback; - callback = isSorted; - isSorted = false; - } - // init value cache for large arrays - var isLarge = !isSorted && length > 74; - if (isLarge) { - var cache = {}; - } - if (callback) { - seen = []; - callback = createCallback(callback, thisArg); - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isLarge) { - // manually coerce `computed` to a string because `hasOwnProperty`, in - // some older versions of Firefox, coerces objects incorrectly - seen = hasOwnProperty.call(cache, computed + '') ? cache[computed] : (cache[computed] = []); - } - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * Creates an array with all occurrences of the passed values removed using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {Mixed} [value1, value2, ...] Values to remove. - * @returns {Array} Returns a new filtered array. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - var index = -1, - length = array ? array.length : 0, - contains = cachedContains(arguments, 1, 20), - result = []; - - while (++index < length) { - var value = array[index]; - if (!contains(value)) { - result.push(value); - } - } - return result; - } - - /** - * Groups the elements of each array at their corresponding indexes. Useful for - * separate data sources that are coordinated through matching array indexes. - * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix - * in a similar fashion. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} [array1, array2, ...] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); - * // => [['moe', 30, true], ['larry', 40, false], ['curly', 50, false]] - */ - function zip(array) { - var index = -1, - length = array ? max(pluck(arguments, 'length')) : 0, - result = Array(length); - - while (++index < length) { - result[index] = pluck(arguments, index); - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that is restricted to executing `func` only after it is - * called `n` times. The `func` is executed with the `this` binding of the - * created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Number} n The number of times the function must be called before - * it is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var renderNotes = _.after(notes.length, render); - * _.forEach(notes, function(note) { - * note.asyncSave({ 'success': renderNotes }); - * }); - * // `renderNotes` is run once, after all notes have saved - */ - function after(n, func) { - if (n < 1) { - return func(); - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * passed to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {Mixed} [thisArg] The `this` binding of `func`. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'moe' }, 'hi'); - * func(); - * // => 'hi moe' - */ - function bind(func, thisArg) { - // use `Function#bind` if it exists and is fast - // (in V8 `Function#bind` is slower except when partially applied) - return isBindFast || (nativeBind && arguments.length > 2) - ? nativeBind.call.apply(nativeBind, arguments) - : createBound(func, thisArg, slice.call(arguments, 2)); - } - - /** - * Binds methods on `object` to `object`, overwriting the existing method. - * If no method names are provided, all the function properties of `object` - * will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {String} [methodName1, methodName2, ...] Method names on the object to bind. - * @returns {Object} Returns `object`. - * @example - * - * var buttonView = { - * 'label': 'lodash', - * 'onClick': function() { alert('clicked: ' + this.label); } - * }; - * - * _.bindAll(buttonView); - * jQuery('#lodash_button').on('click', buttonView.onClick); - * // => When the button is clicked, `this.label` will have the correct value - */ - function bindAll(object) { - var funcs = arguments, - index = funcs.length > 1 ? 0 : (funcs = functions(object), -1), - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = bind(object[key], object); - } - return object; - } - - /** - * Creates a function that is the composition of the passed functions, - * where each function consumes the return value of the function that follows. - * In math terms, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} [func1, func2, ...] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var greet = function(name) { return 'hi: ' + name; }; - * var exclaim = function(statement) { return statement + '!'; }; - * var welcome = _.compose(exclaim, greet); - * welcome('moe'); - * // => 'hi: moe!' - */ - function compose() { - var funcs = arguments; - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. Pass - * `true` for `immediate` to cause debounce to invoke `func` on the leading, - * instead of the trailing, edge of the `wait` timeout. Subsequent calls to - * the debounced function will return the result of the last `func` call. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {Number} wait The number of milliseconds to delay. - * @param {Boolean} immediate A flag to indicate execution is on the leading - * edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * var lazyLayout = _.debounce(calculateLayout, 300); - * jQuery(window).on('resize', lazyLayout); - */ - function debounce(func, wait, immediate) { - var args, - result, - thisArg, - timeoutId; - - function delayed() { - timeoutId = null; - if (!immediate) { - result = func.apply(thisArg, args); - } - } - return function() { - var isImmediate = immediate && !timeoutId; - args = arguments; - thisArg = this; - - clearTimeout(timeoutId); - timeoutId = setTimeout(delayed, wait); - - if (isImmediate) { - result = func.apply(thisArg, args); - } - return result; - }; - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be passed to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {Number} wait The number of milliseconds to delay execution. - * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. - * @returns {Number} Returns the `setTimeout` timeout id. - * @example - * - * var log = _.bind(console.log, console); - * _.delay(log, 1000, 'logged later'); - * // => 'logged later' (Appears after one second.) - */ - function delay(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be passed to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. - * @returns {Number} Returns the `setTimeout` timeout id. - * @example - * - * _.defer(function() { alert('deferred'); }); - * // returns from the function before `alert` is called - */ - function defer(func) { - var args = slice.call(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Creates a function that, when called, invokes `object[methodName]` and - * prepends any additional `lateBind` arguments to those passed to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {String} methodName The method name. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'moe', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.lateBind(object, 'greet', 'hi'); - * func(); - * // => 'hi moe' - * - * object.greet = function(greeting) { - * return greeting + ', ' + this.name + '!'; - * }; - * - * func(); - * // => 'hi, moe!' - */ - function lateBind(object, methodName) { - return createBound(methodName, object, slice.call(arguments, 2)); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * passed, it will be used to determine the cache key for storing the result - * based on the arguments passed to the memoized function. By default, the first - * argument passed to the memoized function is used as the cache key. The `func` - * is executed with the `this` binding of the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - */ - function memoize(func, resolver) { - var cache = {}; - return function() { - var key = resolver ? resolver.apply(this, arguments) : arguments[0]; - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - }; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // Application is only created once. - */ - function once(func) { - var result, - ran = false; - - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those passed to the new function. This - * method is similar to `bind`, except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ': ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('moe'); - * // => 'hi: moe' - */ - function partial(func) { - return createBound(func, slice.call(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` - * function at most once per every `wait` milliseconds. If the throttled - * function is invoked more than once during the `wait` timeout, `func` will - * also be called on the trailing edge of the timeout. Subsequent calls to the - * throttled function will return the result of the last `func` call. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {Number} wait The number of milliseconds to throttle executions to. - * @returns {Function} Returns the new throttled function. - * @example - * - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - */ - function throttle(func, wait) { - var args, - result, - thisArg, - timeoutId, - lastCalled = 0; - - function trailingCall() { - lastCalled = new Date; - timeoutId = null; - result = func.apply(thisArg, args); - } - return function() { - var now = new Date, - remaining = wait - (now - lastCalled); - - args = arguments; - thisArg = this; - - if (remaining <= 0) { - clearTimeout(timeoutId); - lastCalled = now; - result = func.apply(thisArg, args); - } - else if (!timeoutId) { - timeoutId = setTimeout(trailingCall, remaining); - } - return result; - }; - } - - /** - * Creates a function that passes `value` to the `wrapper` function as its - * first argument. Additional arguments passed to the function are appended - * to those passed to the `wrapper` function. The `wrapper` is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Mixed} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var hello = function(name) { return 'hello ' + name; }; - * hello = _.wrap(hello, function(func) { - * return 'before, ' + func('moe') + ', after'; - * }); - * hello(); - * // => 'before, hello moe, after' - */ - function wrap(value, wrapper) { - return function() { - var args = [value]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {String} string The string to escape. - * @returns {String} Returns the escaped string. - * @example - * - * _.escape('Moe, Larry & Curly'); - * // => "Moe, Larry & Curly" - */ - function escape(string) { - return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This function returns the first argument passed to it. - * - * Note: It is used throughout Lo-Dash as a default callback. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Mixed} value Any value. - * @returns {Mixed} Returns `value`. - * @example - * - * var moe = { 'name': 'moe' }; - * moe === _.identity(moe); - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds functions properties of `object` to the `lodash` function and chainable - * wrapper. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object of function properties to add to `lodash`. - * @example - * - * _.mixin({ - * 'capitalize': function(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * }); - * - * _.capitalize('larry'); - * // => 'Larry' - * - * _('curly').capitalize(); - * // => 'Curly' - */ - function mixin(object) { - forEach(functions(object), function(methodName) { - var func = lodash[methodName] = object[methodName]; - - lodash.prototype[methodName] = function() { - var args = [this.__wrapped__]; - push.apply(args, arguments); - - var result = func.apply(lodash, args); - if (this.__chain__) { - result = new lodash(result); - result.__chain__ = true; - } - return result; - }; - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - window._ = oldDash; - return this; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is passed, a number between `0` and the given number will be returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Number} [min=0] The minimum possible value. - * @param {Number} [max=1] The maximum possible value. - * @returns {Number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => a number between 1 and 5 - * - * _.random(5); - * // => also a number between 1 and 5 - */ - function random(min, max) { - if (min == null && max == null) { - max = 1; - } - min = +min || 0; - if (max == null) { - max = min; - min = 0; - } - return min + floor(nativeRandom() * ((+max || 0) - min + 1)); - } - - /** - * Resolves the value of `property` on `object`. If `property` is a function - * it will be invoked and its result returned, else the property value is - * returned. If `object` is falsey, then `null` is returned. - * - * @deprecated - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {String} property The property to get the value of. - * @returns {Mixed} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, property) { - // based on Backbone's private `getValue` function - // https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L1419-1424 - var value = object ? object[property] : null; - return isFunction(value) ? object[property]() : value; - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp` - * build and avoiding `_.template` use, or loading Lo-Dash in a sandboxed page. - * See http://developer.chrome.com/trunk/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {String} text The template text. - * @param {Obect} data The data object used to populate the text. - * @param {Object} options The options object. - * escape - The "escape" delimiter regexp. - * evaluate - The "evaluate" delimiter regexp. - * interpolate - The "interpolate" delimiter regexp. - * sourceURL - The sourceURL of the template's compiled source. - * variable - The data object variable name. - * - * @returns {Function|String} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'moe' }); - * // => 'hello moe' - * - * var list = '<% _.forEach(people, function(name) { %>
          1. <%= name %>
          2. <% }); %>'; - * _.template(list, { 'people': ['moe', 'larry', 'curly'] }); - * // => '
          3. moe
          4. larry
          5. curly
          6. ' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': '').stripTags() -=> 'a linkalert("hello world!")' -``` - -**toSentence** _.toSentence(array, [delimiter, lastDelimiter]) - -Join an array into a human readable sentence. - -```javascript -_.toSentence(['jQuery', 'Mootools', 'Prototype']) -=> 'jQuery, Mootools and Prototype'; - -_.toSentence(['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') -=> 'jQuery, Mootools unt Prototype'; -``` - -**repeat** _.repeat(string, count, [separator]) - -Repeats a string count times. - -```javascript -_.repeat("foo", 3) -=> 'foofoofoo'; - -_.repeat("foo", 3, "bar") -=> 'foobarfoobarfoo' -``` - -**slugify** _.slugify(string) - -Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. - -```javascript -_.slugify("Un éléphant à l'orée du bois") -=> 'un-elephant-a-loree-du-bois'; -``` - -***Caution: this function is charset dependent*** - -## Roadmap ## - -Any suggestions or bug reports are welcome. Just email me or more preferably open an issue. - -## Changelog ## - -### 2.0.0 ### - -* Added prune, humanize functions -* Added _.string (_.str) namespace for Underscore.string library -* Removed includes function - -#### Problems - -We lose two things for `include` and `reverse` methods from `_.string`: - -* Calls like `_('foobar').include('bar')` aren't available; -* Chaining isn't available too. - -But if you need this functionality you can create aliases for conflict functions which will be convenient for you: - -```javascript -_.mixin({ - includeString: _.str.include, - reverseString: _.str.reverse -}) - -// Now wrapper calls and chaining are available. -_('foobar').chain().reverseString().includeString('rab').value() -``` - -#### Standalone Usage - -If you are using Underscore.string without Underscore. You also have `_.string` namespace for it and `_.str` alias -But of course you can just reassign `_` variable with `_.string` - -```javascript -_ = _.string -``` -### 2.2.0 ### - -* Capitalize method behavior changed -* Various perfomance tweaks - -### 2.1.1### - -* Fixed words method bug -* Added classify method - -### 2.1.0 ### - -* AMD support -* Added toSentence method -* Added slugify method -* Lots of speed optimizations - -### 2.0.0 ### - -For upgrading to this version you need to mix in Underscore.string library to Underscore object: - -```javascript -_.mixin(_.string.exports()); -``` - -and all non-conflict Underscore.string functions will be available through Underscore object. -Also function `includes` has been removed, you should replace this function by `_.str.include` -or create alias `_.includes = _.str.include` and all your code will work fine. - -### 1.1.6 ### - -* Fixed reverse and truncate -* Added isBlank, stripTags, inlude(alias for includes) -* Added uglifier compression - -### 1.1.5 ### - -* Added strRight, strRightBack, strLeft, strLeftBack - -### 1.1.4 ### - -* Added pad, lpad, rpad, lrpad methods and aliases center, ljust, rjust -* Integration with Underscore 1.1.6 - -### 1.1.3 ### - -* Added methods: underscored, camelize, dasherize -* Support newer version of npm - -### 1.1.2 ### - -* Created functions: lines, chars, words functions - -### 1.0.2 ### - -* Created integration test suite with underscore.js 1.1.4 (now it's absolutely compatible) -* Removed 'reverse' function, because this function override underscore.js 'reverse' - -## Contribute ## - -* Fork & pull request. Don't forget about tests. -* If you planning add some feature please create issue before. - -Otherwise changes will be rejected. - -## Contributors list ## - -* Esa-Matti Suuronen (), -* Edward Tsech , -* Sasha Koss (), -* Vladimir Dronnikov , -* Pete Kruckenberg (), -* Paul Chavard (), -* Ed Finkler () -* Pavel Pravosud -* Anton Lindqvist () - -## Licence ## - -The MIT License - -Copyright (c) 2011 Esa-Matti Suuronen esa-matti@suuronen.org - -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/spec/fixture/node_modules/grunt/node_modules/underscore.string/Rakefile b/spec/fixture/node_modules/grunt/node_modules/underscore.string/Rakefile deleted file mode 100644 index baa164cd..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/Rakefile +++ /dev/null @@ -1,28 +0,0 @@ -# encoding: utf-8 -task default: :test - -desc 'Use UglifyJS to compress Underscore.string' -task :build do - require 'uglifier' - source = File.read('lib/underscore.string.js') - compressed = Uglifier.compile(source, copyright: false) - File.open('dist/underscore.string.min.js', 'w'){ |f| f.write compressed } - compression_rate = compressed.length.to_f/source.length - puts "compressed dist/underscore.string.min.js: #{compressed.length}/#{source.length} #{(compression_rate * 100).round}%" -end - -desc 'Run tests' -task :test do - pid = spawn('bundle exec serve', err: '/dev/null') - sleep 2 - - puts "Running underscore.string test suite." - result1 = system %{phantomjs ./test/run-qunit.js "http://localhost:4000/test/test.html"} - - puts "Running Underscore test suite." - result2 = system %{phantomjs ./test/run-qunit.js "http://localhost:4000/test/test_underscore/test.html"} - - Process.kill 'INT', pid - - exit(result1 && result2 ? 0 : 1) -end \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/dist/underscore.string.min.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/dist/underscore.string.min.js deleted file mode 100644 index cd436e19..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/dist/underscore.string.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(a){"use strict";var b=String.prototype.trim,c=String.prototype.trimRight,d=String.prototype.trimLeft,e=function(a){return a*1||0},f=function(a,b,c){a+="",b=~~b;for(var d=[];b>0;d[--b]=a);return d.join(c==null?"":c)},g=function(a){return Array.prototype.slice.call(a)},h=function(a){return a!=null?"["+m.escapeRegExp(""+a)+"]":"\\s"},i={lt:"<",gt:">",quot:'"',apos:"'",amp:"&"},j={};for(var k in i)j[i[k]]=k;var l=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}var b=f,c=function(){return c.cache.hasOwnProperty(arguments[0])||(c.cache[arguments[0]]=c.parse(arguments[0])),c.format.call(null,c.cache[arguments[0]],arguments)};return c.format=function(c,d){var e=1,f=c.length,g="",h,i=[],j,k,m,n,o,p;for(j=0;j=0?"+"+h:h,o=m[4]?m[4]=="0"?"0":m[4].charAt(1):" ",p=m[6]-String(h).length,n=m[6]?b(o,p):"",i.push(m[5]?h+n:n+h)}}return i.join("")},c.cache={},c.parse=function(a){var b=a,c=[],d=[],e=0;while(b){if((c=/^[^\x25]+/.exec(b))!==null)d.push(c[0]);else if((c=/^\x25{2}/.exec(b))!==null)d.push("%");else{if((c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b))===null)throw new Error("[_.sprintf] huh?");if(c[2]){e|=1;var f=[],g=c[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(g))===null)throw new Error("[_.sprintf] huh?");f.push(h[1]);while((g=g.substring(h[0].length))!=="")if((h=/^\.([a-z_][a-z_\d]*)/i.exec(g))!==null)f.push(h[1]);else{if((h=/^\[(\d+)\]/.exec(g))===null)throw new Error("[_.sprintf] huh?");f.push(h[1])}c[2]=f}else e|=2;if(e===3)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");d.push(c)}b=b.substring(c[0].length)}return d},c}(),m={VERSION:"2.1.1",isBlank:function(a){return/^\s*$/.test(a)},stripTags:function(a){return(""+a).replace(/<\/?[^>]+>/g,"")},capitalize:function(a){return a+="",a.charAt(0).toUpperCase()+a.substring(1)},chop:function(a,b){a+="",b=~~b||a.length;var c=[];for(var d=0;d"']/g,function(a){return"&"+j[a]+";"})},unescapeHTML:function(a){return(""+a).replace(/\&([^;]+);/g,function(a,b){var c;return b in i?i[b]:(c=b.match(/^#x([\da-fA-F]+)$/))?String.fromCharCode(parseInt(c[1],16)):(c=b.match(/^#(\d+)$/))?String.fromCharCode(~~c[1]):a})},escapeRegExp:function(a){return a.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1")},insert:function(a,b,c){var d=m.chars(a);return d.splice(~~b,0,""+c),d.join("")},include:function(a,b){return!!~(""+a).indexOf(b)},join:function(){var a=g(arguments);return a.join(a.shift())},lines:function(a){return(""+a).split("\n")},reverse:function(a){return m.chars(a).reverse().join("")},splice:function(a,b,c,d){var e=m.chars(a);return e.splice(~~b,~~c,d),e.join("")},startsWith:function(a,b){return a+="",b+="",a.length>=b.length&&a.substring(0,b.length)===b},endsWith:function(a,b){return a+="",b+="",a.length>=b.length&&a.substring(a.length-b.length)===b},succ:function(a){a+="";var b=m.chars(a);return b.splice(a.length-1,1,String.fromCharCode(a.charCodeAt(a.length-1)+1)),b.join("")},titleize:function(a){return(""+a).replace(/\b./g,function(a){return a.toUpperCase()})},camelize:function(a){return m.trim(a).replace(/[-_\s]+(.)?/g,function(a,b){return b&&b.toUpperCase()})},underscored:function(a){return m.trim(a).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(a){return m.trim(a).replace(/[_\s]+/g,"-").replace(/([A-Z])/g,"-$1").replace(/-+/g,"-").toLowerCase()},classify:function(a){return a+="",m.titleize(a.replace(/_/g," ")).replace(/\s/g,"")},humanize:function(a){return m.capitalize(this.underscored(a).replace(/_id$/,"").replace(/_/g," "))},trim:function(a,c){return a+="",!c&&b?b.call(a):(c=h(c),a.replace(new RegExp("^"+c+"+|"+c+"+$","g"),""))},ltrim:function(a,b){return a+="",!b&&d?d.call(a):(b=h(b),a.replace(new RegExp("^"+b+"+"),""))},rtrim:function(a,b){return a+="",!b&&c?c.call(a):(b=h(b),a.replace(new RegExp(b+"+$"),""))},truncate:function(a,b,c){return a+="",c=c||"...",b=~~b,a.length>b?a.slice(0,b)+c:a},prune:function(a,b,c){a+="",b=~~b,c=c!=null?""+c:"...";var d,e,f=a.replace(/\W/g,function(a){return a.toUpperCase()!==a.toLowerCase()?"A":" "});return e=f.charAt(b),d=f.slice(0,b),e&&e.match(/\S/)&&(d=d.replace(/\s\S+$/,"")),d=m.rtrim(d),(d+c).length>a.length?a:a.substring(0,d.length)+c},words:function(a,b){return m.trim(a,b).split(b||/\s+/)},pad:function(a,b,c,d){a+="";var e=0;b=~~b,c?c.length>1&&(c=c.charAt(0)):c=" ";switch(d){case"right":return e=b-a.length,a+f(c,e);case"both":return e=b-a.length,f(c,Math.ceil(e/2))+a+f(c,Math.floor(e/2));default:return e=b-a.length,f(c,e)+a}},lpad:function(a,b,c){return m.pad(a,b,c)},rpad:function(a,b,c){return m.pad(a,b,c,"right")},lrpad:function(a,b,c){return m.pad(a,b,c,"both")},sprintf:l,vsprintf:function(a,b){return b.unshift(a),l.apply(null,b)},toNumber:function(a,b){a+="";var c=e(e(a).toFixed(~~b));return c===0&&!a.match(/^0+$/)?Number.NaN:c},strRight:function(a,b){a+="",b=b!=null?""+b:b;var c=b?a.indexOf(b):-1;return~c?a.slice(c+b.length,a.length):a},strRightBack:function(a,b){a+="",b=b!=null?""+b:b;var c=b?a.lastIndexOf(b):-1;return~c?a.slice(c+b.length,a.length):a},strLeft:function(a,b){a+="",b=b!=null?""+b:b;var c=b?a.indexOf(b):-1;return~c?a.slice(0,c):a},strLeftBack:function(a,b){a+="",b=b!=null?""+b:b;var c=a.lastIndexOf(b);return~c?a.slice(0,c):a},toSentence:function(a,b,c){b||(b=", "),c||(c=" and ");var d=a.length,e="";for(var f=0;f -// Underscore.strings is freely distributable under the terms of the MIT license. -// Documentation: https://github.com/epeli/underscore.string -// Some code is borrowed from MooTools and Alexandru Marasteanu. - -// Version 2.2.0rc - -(function(root){ - 'use strict'; - - // Defining helper functions. - - var nativeTrim = String.prototype.trim; - var nativeTrimRight = String.prototype.trimRight; - var nativeTrimLeft = String.prototype.trimLeft; - - var parseNumber = function(source) { return source * 1 || 0; }; - - var strRepeat = function(str, qty, separator){ - // ~~var — is the fastest available way to convert anything to Integer in javascript. - // We'll use it extensively in this lib. - str += ''; qty = ~~qty; - for (var repeat = []; qty > 0; repeat[--qty] = str) {} - return repeat.join(separator == null ? '' : separator); - }; - - var slice = function(a){ - return Array.prototype.slice.call(a); - }; - - var defaultToWhiteSpace = function(characters){ - if (characters != null) { - return '[' + _s.escapeRegExp(''+characters) + ']'; - } - return '\\s'; - }; - - var escapeChars = { - lt: '<', - gt: '>', - quot: '"', - apos: "'", - amp: '&' - }; - - var reversedEscapeChars = {}; - for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; } - - // sprintf() for JavaScript 0.7-beta1 - // http://www.diveintojavascript.com/projects/javascript-sprintf - // - // Copyright (c) Alexandru Marasteanu - // All rights reserved. - - var sprintf = (function() { - function get_type(variable) { - return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); - } - - var str_repeat = strRepeat; - - var str_format = function() { - if (!str_format.cache.hasOwnProperty(arguments[0])) { - str_format.cache[arguments[0]] = str_format.parse(arguments[0]); - } - return str_format.format.call(null, str_format.cache[arguments[0]], arguments); - }; - - str_format.format = function(parse_tree, argv) { - var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; - for (i = 0; i < tree_length; i++) { - node_type = get_type(parse_tree[i]); - if (node_type === 'string') { - output.push(parse_tree[i]); - } - else if (node_type === 'array') { - match = parse_tree[i]; // convenience purposes only - if (match[2]) { // keyword argument - arg = argv[cursor]; - for (k = 0; k < match[2].length; k++) { - if (!arg.hasOwnProperty(match[2][k])) { - throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k])); - } - arg = arg[match[2][k]]; - } - } else if (match[1]) { // positional argument (explicit) - arg = argv[match[1]]; - } - else { // positional argument (implicit) - arg = argv[cursor++]; - } - - if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { - throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg))); - } - switch (match[8]) { - case 'b': arg = arg.toString(2); break; - case 'c': arg = String.fromCharCode(arg); break; - case 'd': arg = parseInt(arg, 10); break; - case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; - case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; - case 'o': arg = arg.toString(8); break; - case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; - case 'u': arg = Math.abs(arg); break; - case 'x': arg = arg.toString(16); break; - case 'X': arg = arg.toString(16).toUpperCase(); break; - } - arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); - pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; - pad_length = match[6] - String(arg).length; - pad = match[6] ? str_repeat(pad_character, pad_length) : ''; - output.push(match[5] ? arg + pad : pad + arg); - } - } - return output.join(''); - }; - - str_format.cache = {}; - - str_format.parse = function(fmt) { - var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; - while (_fmt) { - if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { - parse_tree.push(match[0]); - } - else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { - parse_tree.push('%'); - } - else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { - if (match[2]) { - arg_names |= 1; - var field_list = [], replacement_field = match[2], field_match = []; - if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { - if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { - field_list.push(field_match[1]); - } - else { - throw new Error('[_.sprintf] huh?'); - } - } - } - else { - throw new Error('[_.sprintf] huh?'); - } - match[2] = field_list; - } - else { - arg_names |= 2; - } - if (arg_names === 3) { - throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported'); - } - parse_tree.push(match); - } - else { - throw new Error('[_.sprintf] huh?'); - } - _fmt = _fmt.substring(match[0].length); - } - return parse_tree; - }; - - return str_format; - })(); - - - - // Defining underscore.string - - var _s = { - - VERSION: '2.2.0rc', - - isBlank: function(str){ - return (/^\s*$/).test(str); - }, - - stripTags: function(str){ - return (''+str).replace(/<\/?[^>]+>/g, ''); - }, - - capitalize : function(str) { - str += ''; - return str.charAt(0).toUpperCase() + str.substring(1); - }, - - chop: function(str, step){ - str = str+''; - step = ~~step || str.length; - var arr = []; - for (var i = 0; i < str.length; i += step) - arr.push(str.slice(i,i + step)); - return arr; - }, - - clean: function(str){ - return _s.strip(str).replace(/\s+/g, ' '); - }, - - count: function(str, substr){ - str += ''; substr += ''; - return str.split(substr).length - 1; - }, - - chars: function(str) { - return (''+str).split(''); - }, - - escapeHTML: function(str) { - return (''+str).replace(/[&<>"']/g, function(match){ return '&' + reversedEscapeChars[match] + ';'; }); - }, - - unescapeHTML: function(str) { - return (''+str).replace(/\&([^;]+);/g, function(entity, entityCode){ - var match; - - if (entityCode in escapeChars) { - return escapeChars[entityCode]; - } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { - return String.fromCharCode(parseInt(match[1], 16)); - } else if (match = entityCode.match(/^#(\d+)$/)) { - return String.fromCharCode(~~match[1]); - } else { - return entity; - } - }); - }, - - escapeRegExp: function(str){ - // From MooTools core 1.2.4 - return str.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); - }, - - insert: function(str, i, substr){ - var arr = _s.chars(str); - arr.splice(~~i, 0, ''+substr); - return arr.join(''); - }, - - include: function(str, needle){ - return !!~(''+str).indexOf(needle); - }, - - join: function() { - var args = slice(arguments); - return args.join(args.shift()); - }, - - lines: function(str) { - return (''+str).split("\n"); - }, - - reverse: function(str){ - return _s.chars(str).reverse().join(''); - }, - - splice: function(str, i, howmany, substr){ - var arr = _s.chars(str); - arr.splice(~~i, ~~howmany, substr); - return arr.join(''); - }, - - startsWith: function(str, starts){ - str += ''; starts += ''; - return str.length >= starts.length && str.substring(0, starts.length) === starts; - }, - - endsWith: function(str, ends){ - str += ''; ends += ''; - return str.length >= ends.length && str.substring(str.length - ends.length) === ends; - }, - - succ: function(str){ - str += ''; - var arr = _s.chars(str); - arr.splice(str.length-1, 1, String.fromCharCode(str.charCodeAt(str.length-1) + 1)); - return arr.join(''); - }, - - titleize: function(str){ - return (''+str).replace(/\b./g, function(ch){ return ch.toUpperCase(); }); - }, - - camelize: function(str){ - return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, chr){ - return chr && chr.toUpperCase(); - }); - }, - - underscored: function(str){ - return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); - }, - - dasherize: function(str){ - return _s.trim(str).replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase(); - }, - - classify: function(str){ - str += ''; - return _s.titleize(str.replace(/_/g, ' ')).replace(/\s/g, '') - }, - - humanize: function(str){ - return _s.capitalize(this.underscored(str).replace(/_id$/,'').replace(/_/g, ' ')); - }, - - trim: function(str, characters){ - str += ''; - if (!characters && nativeTrim) { return nativeTrim.call(str); } - characters = defaultToWhiteSpace(characters); - return str.replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), ''); - }, - - ltrim: function(str, characters){ - str+=''; - if (!characters && nativeTrimLeft) { - return nativeTrimLeft.call(str); - } - characters = defaultToWhiteSpace(characters); - return str.replace(new RegExp('^' + characters + '+'), ''); - }, - - rtrim: function(str, characters){ - str+=''; - if (!characters && nativeTrimRight) { - return nativeTrimRight.call(str); - } - characters = defaultToWhiteSpace(characters); - return str.replace(new RegExp(characters + '+$'), ''); - }, - - truncate: function(str, length, truncateStr){ - str += ''; truncateStr = truncateStr || '...'; - length = ~~length; - return str.length > length ? str.slice(0, length) + truncateStr : str; - }, - - /** - * _s.prune: a more elegant version of truncate - * prune extra chars, never leaving a half-chopped word. - * @author github.com/sergiokas - */ - prune: function(str, length, pruneStr){ - str += ''; length = ~~length; - pruneStr = pruneStr != null ? ''+pruneStr : '...'; - - var pruned, borderChar, template = str.replace(/\W/g, function(ch){ - return (ch.toUpperCase() !== ch.toLowerCase()) ? 'A' : ' '; - }); - - borderChar = template.charAt(length); - - pruned = template.slice(0, length); - - // Check if we're in the middle of a word - if (borderChar && borderChar.match(/\S/)) - pruned = pruned.replace(/\s\S+$/, ''); - - pruned = _s.rtrim(pruned); - - return (pruned+pruneStr).length > str.length ? str : str.substring(0, pruned.length)+pruneStr; - }, - - words: function(str, delimiter) { - return _s.trim(str, delimiter).split(delimiter || /\s+/); - }, - - pad: function(str, length, padStr, type) { - str += ''; - - var padlen = 0; - - length = ~~length; - - if (!padStr) { - padStr = ' '; - } else if (padStr.length > 1) { - padStr = padStr.charAt(0); - } - - switch(type) { - case 'right': - padlen = (length - str.length); - return str + strRepeat(padStr, padlen); - case 'both': - padlen = (length - str.length); - return strRepeat(padStr, Math.ceil(padlen/2)) + - str + - strRepeat(padStr, Math.floor(padlen/2)); - default: // 'left' - padlen = (length - str.length); - return strRepeat(padStr, padlen) + str; - } - }, - - lpad: function(str, length, padStr) { - return _s.pad(str, length, padStr); - }, - - rpad: function(str, length, padStr) { - return _s.pad(str, length, padStr, 'right'); - }, - - lrpad: function(str, length, padStr) { - return _s.pad(str, length, padStr, 'both'); - }, - - sprintf: sprintf, - - vsprintf: function(fmt, argv){ - argv.unshift(fmt); - return sprintf.apply(null, argv); - }, - - toNumber: function(str, decimals) { - str += ''; - var num = parseNumber(parseNumber(str).toFixed(~~decimals)); - return num === 0 && !str.match(/^0+$/) ? Number.NaN : num; - }, - - strRight: function(str, sep){ - str += ''; sep = sep != null ? ''+sep : sep; - var pos = !sep ? -1 : str.indexOf(sep); - return ~pos ? str.slice(pos+sep.length, str.length) : str; - }, - - strRightBack: function(str, sep){ - str += ''; sep = sep != null ? ''+sep : sep; - var pos = !sep ? -1 : str.lastIndexOf(sep); - return ~pos ? str.slice(pos+sep.length, str.length) : str; - }, - - strLeft: function(str, sep){ - str += ''; sep = sep != null ? ''+sep : sep; - var pos = !sep ? -1 : str.indexOf(sep); - return ~pos ? str.slice(0, pos) : str; - }, - - strLeftBack: function(str, sep){ - str += ''; sep = sep != null ? ''+sep : sep; - var pos = str.lastIndexOf(sep); - return ~pos ? str.slice(0, pos) : str; - }, - - toSentence: function(array, separator, lastSeparator) { - separator || (separator = ', '); - lastSeparator || (lastSeparator = ' and '); - var length = array.length, str = ''; - - for (var i = 0; i < length; i++) { - str += array[i]; - if (i === (length - 2)) { str += lastSeparator; } - else if (i < (length - 1)) { str += separator; } - } - - return str; - }, - - slugify: function(str) { - var from = "ąàáäâãćęèéëêìíïîłńòóöôõùúüûñçżź", - to = "aaaaaaceeeeeiiiilnooooouuuunczz", - regex = new RegExp(defaultToWhiteSpace(from), 'g'); - - str = (''+str).toLowerCase(); - - str = str.replace(regex, function(ch){ - var index = from.indexOf(ch); - return to.charAt(index) || '-'; - }); - - return _s.trim(str.replace(/[^\w\s-]/g, '').replace(/[-\s]+/g, '-'), '-'); - }, - - exports: function() { - var result = {}; - - for (var prop in this) { - if (!this.hasOwnProperty(prop) || ~_s.words('include contains reverse').indexOf(prop)) continue; - result[prop] = this[prop]; - } - - return result; - }, - - repeat: strRepeat - }; - - // Aliases - - _s.strip = _s.trim; - _s.lstrip = _s.ltrim; - _s.rstrip = _s.rtrim; - _s.center = _s.lrpad; - _s.rjust = _s.lpad; - _s.ljust = _s.rpad; - _s.contains = _s.include; - - // CommonJS module is defined - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - // Export module - module.exports = _s; - } - exports._s = _s; - - } else if (typeof define === 'function' && define.amd) { - // Register as a named module with AMD. - define('underscore.string', function() { - return _s; - }); - - } else { - // Integrate with Underscore.js if defined - // or create our own underscore object. - root._ = root._ || {}; - root._.string = root._.str = _s; - } - -}(this || window)); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/package.json b/spec/fixture/node_modules/grunt/node_modules/underscore.string/package.json deleted file mode 100644 index a692a1d1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/package.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "underscore.string", - "version": "2.2.1", - "description": "String manipulation extensions for Underscore.js javascript library.", - "homepage": "http://epeli.github.com/underscore.string/", - "contributors": [ - { - "name": "Esa-Matti Suuronen", - "email": "esa-matti@suuronen.org", - "url": "http://esa-matti.suuronen.org/" - }, - { - "name": "Edward Tsech", - "email": "edtsech@gmail.com" - }, - { - "name": "Sasha Koss", - "email": "kossnocorp@gmail.com", - "url": "http://koss.nocorp.me/" - }, - { - "name": "Vladimir Dronnikov", - "email": "dronnikov@gmail.com" - }, - { - "name": "Pete Kruckenberg", - "email": "https://github.com/kruckenb", - "url": "" - }, - { - "name": "Paul Chavard", - "email": "paul@chavard.net", - "url": "" - }, - { - "name": "Ed Finkler", - "email": "coj@funkatron.com", - "url": "" - }, - { - "name": "Pavel Pravosud", - "email": "rwz@duckroll.ru" - } - ], - "keywords": [ - "underscore", - "string" - ], - "main": "./lib/underscore.string", - "directories": { - "lib": "./lib" - }, - "engines": { - "node": "*" - }, - "repository": { - "type": "git", - "url": "https://github.com/epeli/underscore.string.git" - }, - "bugs": { - "url": "https://github.com/epeli/underscore.string/issues" - }, - "licenses": [ - { - "type": "MIT" - } - ], - "_id": "underscore.string@2.2.1", - "dist": { - "shasum": "d7c0fa2af5d5a1a67f4253daee98132e733f0f19", - "tarball": "http://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz" - }, - "_from": "underscore.string@~2.2.1", - "_npmVersion": "1.2.32", - "_npmUser": { - "name": "epeli", - "email": "esa-matti@suuronen.org" - }, - "maintainers": [ - { - "name": "edtsech", - "email": "edtsech@gmail.com" - }, - { - "name": "rwz", - "email": "rwz@duckroll.ru" - }, - { - "name": "epeli", - "email": "esa-matti@suuronen.org" - } - ], - "_shasum": "d7c0fa2af5d5a1a67f4253daee98132e733f0f19", - "_resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/run-qunit.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/run-qunit.js deleted file mode 100644 index 326658ed..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/run-qunit.js +++ /dev/null @@ -1,44 +0,0 @@ -function waitFor(test, complete, timeout) { - var result, start = new Date().getTime() - setInterval(function interval() { - if ((new Date().getTime() - start < timeout) && !result) { - result = test() - } else { - if (!result) { - phantom.exit(1) - } else { - complete() - clearInterval(interval) - } - } - }, 100) -} - - -var page = new WebPage() - -page.onConsoleMessage = function(msg) { - console.log(msg) -} - -page.open(phantom.args[0], function(status) { - waitFor(function() { - return page.evaluate(function(){ - var el = document.getElementById('qunit-testresult') - return el && el.innerText.match('completed') - }) - }, function() { - var failures = page.evaluate(function() { - var el = document.getElementById('qunit-testresult'), - fails = document.getElementsByClassName('fail') - - for (var i = 0; i < fails.length; i++) - console.log(fails[i].innerText) - - console.log(el.innerText) - - return parseInt(el.getElementsByClassName('failed')[0].innerHTML) - }) - phantom.exit(failures > 0 ? 1 : 0) - }, 10000) -}) \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/speed.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/speed.js deleted file mode 100644 index 43464147..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/speed.js +++ /dev/null @@ -1,138 +0,0 @@ -(function() { - - JSLitmus.test('trimNoNative', function() { - return _.trim(" foobar ", " "); - }); - - JSLitmus.test('trim', function() { - return _.trim(" foobar "); - }); - - JSLitmus.test('trim object-oriented', function() { - return _(" foobar ").trim(); - }); - - JSLitmus.test('trim jQuery', function() { - return jQuery.trim(" foobar "); - }); - - JSLitmus.test('ltrimp', function() { - return _.ltrim(" foobar ", " "); - }); - - JSLitmus.test('rtrimp', function() { - return _.rtrim(" foobar ", " "); - }); - - JSLitmus.test('startsWith', function() { - return _.startsWith("foobar", "foo"); - }); - - JSLitmus.test('endsWith', function() { - return _.endsWith("foobar", "xx"); - }); - - JSLitmus.test('chop', function(){ - return _('whitespace').chop(2); - }); - - JSLitmus.test('count', function(){ - return _('Hello worls').count('l'); - }); - - JSLitmus.test('insert', function() { - return _('Hello ').insert(6, 'world'); - }); - - JSLitmus.test('splice', function() { - return _('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'); - }); - - JSLitmus.test('succ', function(){ - var let = 'a', alphabet = []; - - for (var i=0; i < 26; i++) { - alphabet.push(let); - let = _(let).succ(); - } - - return alphabet; - }); - - JSLitmus.test('titleize', function(){ - return _('the titleize string method').titleize(); - }); - - JSLitmus.test('truncate', function(){ - return _('Hello world').truncate(5); - }); - - JSLitmus.test('prune', function(){ - return _('Hello world').prune(5); - }); - - JSLitmus.test('isBlank', function(){ - return _('').isBlank(); - }); - - JSLitmus.test('escapeHTML', function(){ - _('
            Blah blah blah
            ').escapeHTML(); - }); - - JSLitmus.test('unescapeHTML', function(){ - _('<div>Blah blah blah</div>').unescapeHTML(); - }); - - JSLitmus.test('reverse', function(){ - _('Hello World').reverse(); - }); - - JSLitmus.test('pad default', function(){ - _('foo').pad(12); - }); - - JSLitmus.test('pad hash left', function(){ - _('foo').pad(12, '#'); - }); - - JSLitmus.test('pad hash right', function(){ - _('foo').pad(12, '#', 'right'); - }); - - JSLitmus.test('pad hash both', function(){ - _('foo').pad(12, '#', 'both'); - }); - - JSLitmus.test('pad hash both longPad', function(){ - _('foo').pad(12, 'f00f00f00', 'both'); - }); - - JSLitmus.test('toNumber', function(){ - _('10.232323').toNumber(2); - }); - - JSLitmus.test('strRight', function(){ - _('aaa_bbb_ccc').strRight('_'); - }); - - JSLitmus.test('strRightBack', function(){ - _('aaa_bbb_ccc').strRightBack('_'); - }); - - JSLitmus.test('strLeft', function(){ - _('aaa_bbb_ccc').strLeft('_'); - }); - - JSLitmus.test('strLeftBack', function(){ - _('aaa_bbb_ccc').strLeftBack('_'); - }); - - JSLitmus.test('join', function(){ - _('separator').join(1, 2, 3, 4, 5, 6, 7, 8, 'foo', 'bar', 'lol', 'wut'); - }); - - JSLitmus.test('slugify', function(){ - _("Un éléphant à l'orée du bois").slugify(); - }); - -})(); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/strings.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/strings.js deleted file mode 100644 index f700abf1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/strings.js +++ /dev/null @@ -1,438 +0,0 @@ -$(document).ready(function() { - - // Include Underscore.string methods to Underscore namespace - _.mixin(_.str.exports()); - - module("String extensions"); - - test("Strings: trim", function() { - equals(_.trim(123), "123", "Non string"); - equals(_(" foo").trim(), "foo"); - equals(_("foo ").trim(), "foo"); - equals(_(" foo ").trim(), "foo"); - equals(_(" foo ").trim(), "foo"); - equals(_(" foo ", " ").trim(), "foo", "Manually set whitespace"); - - equals(_("ffoo").trim("f"), "oo"); - equals(_("ooff").trim("f"), "oo"); - equals(_("ffooff").trim("f"), "oo"); - - - equals(_("_-foobar-_").trim("_-"), "foobar"); - - equals(_("http://foo/").trim("/"), "http://foo"); - equals(_("c:\\").trim('\\'), "c:"); - - equals(_(123).trim(), '123'); - equals(_(123).trim(3), '12'); - }); - - test("Strings: ltrim", function() { - equals(_(" foo").ltrim(), "foo"); - equals(_(" foo").ltrim(), "foo"); - equals(_("foo ").ltrim(), "foo "); - equals(_(" foo ").ltrim(), "foo "); - - - equals(_("ffoo").ltrim("f"), "oo"); - equals(_("ooff").ltrim("f"), "ooff"); - equals(_("ffooff").ltrim("f"), "ooff"); - - equals(_("_-foobar-_").ltrim("_-"), "foobar-_"); - - equals(_(123).ltrim(1), '23'); - }); - - test("Strings: rtrim", function() { - equals(_("http://foo/").rtrim("/"), "http://foo", 'clean trailing slash'); - equals(_(" foo").rtrim(), " foo"); - equals(_("foo ").rtrim(), "foo"); - equals(_("foo ").rtrim(), "foo"); - equals(_("foo bar ").rtrim(), "foo bar"); - equals(_(" foo ").rtrim(), " foo"); - - equals(_("ffoo").rtrim("f"), "ffoo"); - equals(_("ooff").rtrim("f"), "oo"); - equals(_("ffooff").rtrim("f"), "ffoo"); - - equals(_("_-foobar-_").rtrim("_-"), "_-foobar"); - - equals(_(123).rtrim(3), '12'); - }); - - test("Strings: capitalize", function() { - equals(_("fabio").capitalize(), "Fabio", 'First letter is upper case'); - equals(_.capitalize("fabio"), "Fabio", 'First letter is upper case'); - equals(_.capitalize('FOO'), 'FOO', 'Other letters unchanged'); - equals(_(123).capitalize(), "123", "Non string"); - }); - - test("Strings: join", function() { - equals(_.join("", "foo", "bar"), "foobar", 'basic join'); - equals(_.join("", 1, "foo", 2), "1foo2", 'join numbers and strings'); - equals(_.join(" ","foo", "bar"), "foo bar", 'join with spaces'); - equals(_.join("1", "2", "2"), "212", 'join number strings'); - equals(_.join(1, 2, 2), "212", 'join numbers'); - equals(_(" ").join("foo", "bar"), "foo bar", 'join object oriented'); - }); - - test("Strings: reverse", function() { - equals(_.str.reverse("foo"), "oof" ); - equals(_.str.reverse("foobar"), "raboof" ); - equals(_.str.reverse("foo bar"), "rab oof" ); - equals(_.str.reverse("saippuakauppias"), "saippuakauppias" ); - equals(_.str.reverse(123), "321", "Non string"); - equals(_.str.reverse(123.45), "54.321", "Non string"); - }); - - test("Strings: clean", function() { - equals(_(" foo bar ").clean(), "foo bar"); - equals(_(123).clean(), "123"); - }); - - test("Strings: sprintf", function() { - // Should be very tested function already. Thanks to - // http://www.diveintojavascript.com/projects/sprintf-for-javascript - equals(_.sprintf("Hello %s", "me"), "Hello me", 'basic'); - equals(_("Hello %s").sprintf("me"), "Hello me", 'object'); - equals(_("hello %s").chain().sprintf("me").capitalize().value(), "Hello me", 'Chaining works'); - equals(_.sprintf("%.1f", 1.22222), "1.2", 'round'); - equals(_.sprintf("%.1f", 1.17), "1.2", 'round 2'); - equals(_.sprintf("%(id)d - %(name)s", {id: 824, name: "Hello World"}), "824 - Hello World", 'Named replacements work'); - equals(_.sprintf("%(args[0].id)d - %(args[1].name)s", {args: [{id: 824}, {name: "Hello World"}]}), "824 - Hello World", 'Named replacements with arrays work'); - }); - - - test("Strings: vsprintf", function() { - equals(_.vsprintf("Hello %s", ["me"]), "Hello me", 'basic'); - equals(_("Hello %s").vsprintf(["me"]), "Hello me", 'object'); - equals(_("hello %s").chain().vsprintf(["me"]).capitalize().value(), "Hello me", 'Chaining works'); - equals(_.vsprintf("%.1f", [1.22222]), "1.2", 'round'); - equals(_.vsprintf("%.1f", [1.17]), "1.2", 'round 2'); - equals(_.vsprintf("%(id)d - %(name)s", [{id: 824, name: "Hello World"}]), "824 - Hello World", 'Named replacement works'); - equals(_.vsprintf("%(args[0].id)d - %(args[1].name)s", [{args: [{id: 824}, {name: "Hello World"}]}]), "824 - Hello World", 'Named replacement with arrays works'); - }); - - test("Strings: startsWith", function() { - ok(_("foobar").startsWith("foo"), 'foobar starts with foo'); - ok(!_("oobar").startsWith("foo"), 'oobar does not start with foo'); - ok(_(12345).startsWith(123), '12345 starts with 123'); - ok(!_(2345).startsWith(123), '2345 does not start with 123'); - }); - - test("Strings: endsWith", function() { - ok(_("foobar").endsWith("bar"), 'foobar ends with bar'); - ok(_.endsWith("foobar", "bar"), 'foobar ends with bar'); - ok(_.endsWith("00018-0000062.Plone.sdh264.1a7264e6912a91aa4a81b64dc5517df7b8875994.mp4", "mp4"), 'endsWith .mp4'); - ok(!_("fooba").endsWith("bar"), 'fooba does not end with bar'); - ok(_.endsWith(12345, 45), '12345 ends with 45'); - ok(!_.endsWith(12345, 6), '12345 does not end with 6'); - }); - - test("Strings: include", function() { - ok(_.str.include("foobar", "bar"), 'foobar includes bar'); - ok(!_.str.include("foobar", "buzz"), 'foobar does not includes buzz'); - ok(_.str.include(12345, 34), '12345 includes 34'); - ok(!_.str.contains(12345, 6), '12345 does not includes 6'); - }); - - test('String: chop', function(){ - ok(_('whitespace').chop(2).length === 5, "output ['wh','it','es','pa','ce']"); - ok(_('whitespace').chop(3).length === 4, "output ['whi','tes','pac','e']"); - ok(_('whitespace').chop()[0].length === 10, "output ['whitespace']"); - ok(_(12345).chop(1).length === 5, "output ['1','2','3','4','5']"); - }); - - test('String: clean', function(){ - equals(_.clean(' foo bar '), 'foo bar'); - equals(_.clean(1), '1'); - }); - - test('String: count', function(){ - equals(_('Hello world').count('l'), 3); - equals(_('Hello world').count('Hello'), 1); - equals(_('Hello world').count('foo'), 0); - equals(_('x.xx....x.x').count('x'), 5); - equals(_(12345).count(1), 1); - equals(_(11345).count(1), 2); - }); - - test('String: insert', function(){ - equals(_('Hello ').insert(6, 'Jessy'), 'Hello Jessy'); - equals(_('Hello ').insert(100, 'Jessy'), 'Hello Jessy'); - equals(_(12345).insert(6, 'Jessy'), '12345Jessy'); - }); - - test('String: splice', function(){ - equals(_('https://edtsech@bitbucket.org/edtsech/underscore.strings').splice(30, 7, 'epeli'), - 'https://edtsech@bitbucket.org/epeli/underscore.strings'); - equals(_.splice(12345, 1, 2, 321), '132145', 'Non strings'); - }); - - test('String: succ', function(){ - equals(_('a').succ(), 'b'); - equals(_('A').succ(), 'B'); - equals(_('+').succ(), ','); - equals(_(1).succ(), '2'); - }); - - test('String: titleize', function(){ - equals(_('the titleize string method').titleize(), 'The Titleize String Method'); - equals(_('the titleize string method').titleize(), 'The Titleize String Method'); - equals(_(123).titleize(), '123'); - }); - - test('String: camelize', function(){ - equals(_('the_camelize_string_method').camelize(), 'theCamelizeStringMethod'); - equals(_('-the-camelize-string-method').camelize(), 'TheCamelizeStringMethod'); - equals(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); - equals(_(' the camelize string method').camelize(), 'theCamelizeStringMethod'); - equals(_('the camelize string method').camelize(), 'theCamelizeStringMethod'); - equals(_(123).camelize(), '123'); - }); - - test('String: underscored', function(){ - equals(_('the-underscored-string-method').underscored(), 'the_underscored_string_method'); - equals(_('theUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); - equals(_('TheUnderscoredStringMethod').underscored(), 'the_underscored_string_method'); - equals(_(' the underscored string method').underscored(), 'the_underscored_string_method'); - equals(_(123).underscored(), '123'); - }); - - test('String: dasherize', function(){ - equals(_('the_dasherize_string_method').dasherize(), 'the-dasherize-string-method'); - equals(_('TheDasherizeStringMethod').dasherize(), '-the-dasherize-string-method'); - equals(_('thisIsATest').dasherize(), 'this-is-a-test'); - equals(_('this Is A Test').dasherize(), 'this-is-a-test'); - equals(_('thisIsATest123').dasherize(), 'this-is-a-test123'); - equals(_('123thisIsATest').dasherize(), '123this-is-a-test'); - equals(_('the dasherize string method').dasherize(), 'the-dasherize-string-method'); - equals(_('the dasherize string method ').dasherize(), 'the-dasherize-string-method'); - equals(_('téléphone').dasherize(), 'téléphone'); - equals(_('foo$bar').dasherize(), 'foo$bar'); - equals(_(123).dasherize(), '123'); - }); - - test('String: camelize', function(){ - equals(_.camelize('-moz-transform'), 'MozTransform'); - equals(_.camelize('webkit-transform'), 'webkitTransform'); - equals(_.camelize('under_scored'), 'underScored'); - equals(_.camelize(' with spaces'), 'withSpaces'); - }); - - test('String: join', function(){ - equals(_.join(1, 2, 3, 4), '21314'); - equals(_.join('|', 'foo', 'bar', 'baz'), 'foo|bar|baz'); - }); - - test('String: classify', function(){ - equals(_.classify(1), '1'); - equals(_('some_class_name').classify(), 'SomeClassName'); - }); - - test('String: humanize', function(){ - equals(_('the_humanize_string_method').humanize(), 'The humanize string method'); - equals(_('ThehumanizeStringMethod').humanize(), 'Thehumanize string method'); - equals(_('the humanize string method').humanize(), 'The humanize string method'); - equals(_('the humanize_id string method_id').humanize(), 'The humanize id string method'); - equals(_('the humanize string method ').humanize(), 'The humanize string method'); - equals(_(' capitalize dash-CamelCase_underscore trim ').humanize(), 'Capitalize dash camel case underscore trim'); - equals(_(123).humanize(), '123'); - }); - - test('String: truncate', function(){ - equals(_('Hello world').truncate(6, 'read more'), 'Hello read more'); - equals(_('Hello world').truncate(5), 'Hello...'); - equals(_('Hello').truncate(10), 'Hello'); - equals(_(1234567890).truncate(5), '12345...'); - }); - - test('String: prune', function(){ - equals(_('Hello, cruel world').prune(6, ' read more'), 'Hello read more'); - equals(_('Hello, world').prune(5, 'read a lot more'), 'Hello, world'); - equals(_('Hello, world').prune(5), 'Hello...'); - equals(_('Hello, world').prune(8), 'Hello...'); - equals(_('Hello, cruel world').prune(15), 'Hello, cruel...'); - equals(_('Hello world').prune(22), 'Hello world'); - equals(_('Привет, жеÑтокий мир').prune(6, ' read more'), 'Привет read more'); - equals(_('Привет, мир').prune(6, 'read a lot more'), 'Привет, мир'); - equals(_('Привет, мир').prune(6), 'Привет...'); - equals(_('Привет, мир').prune(8), 'Привет...'); - equals(_('Привет, жеÑтокий мир').prune(16), 'Привет, жеÑтокий...'); - equals(_('Привет, мир').prune(22), 'Привет, мир'); - equals(_(123).prune(10), '123'); - equals(_(123).prune(1,1), '11'); - }); - - test('String: isBlank', function(){ - ok(_('').isBlank()); - ok(_(' ').isBlank()); - ok(_('\n').isBlank()); - ok(!_('a').isBlank()); - ok(!_('0').isBlank()); - ok(!_(0).isBlank()); - }); - - test('String: escapeHTML', function(){ - equals(_('
            Blah & "blah" & \'blah\'
            ').escapeHTML(), - '<div>Blah & "blah" & 'blah'</div>'); - equals(_('<').escapeHTML(), '&lt;'); - equals(_(5).escapeHTML(), '5'); - // equals(_(undefined).escapeHTML(), ''); - }); - - test('String: unescapeHTML', function(){ - equals(_('<div>Blah & "blah" & 'blah'</div>').unescapeHTML(), - '
            Blah & "blah" & \'blah\'
            '); - equals(_('&lt;').unescapeHTML(), '<'); - equals(_(''').unescapeHTML(), "'"); - equals(_(''').unescapeHTML(), "'"); - equals(_('J').unescapeHTML(), "J"); - equals(_('J').unescapeHTML(), "J"); - equals(_('J').unescapeHTML(), "J"); - equals(_('&_#39;').unescapeHTML(), "&_#39;"); - equals(_(''_;').unescapeHTML(), "'_;"); - equals(_('&#38;').unescapeHTML(), "&"); - equals(_('&amp;').unescapeHTML(), "&"); - equals(_(5).unescapeHTML(), '5'); - // equals(_(undefined).unescapeHTML(), ''); - }); - - test('String: words', function() { - equals(_("I love you!").words().length, 3); - equals(_(" I love you! ").words().length, 3); - equals(_("I_love_you!").words('_').length, 3); - equals(_("I-love-you!").words(/-/).length, 3); - equals(_(123).words().length, 1); - }); - - test('String: chars', function() { - equals(_("Hello").chars().length, 5); - equals(_(123).chars().length, 3); - }); - - test('String: lines', function() { - equals(_("Hello\nWorld").lines().length, 2); - equals(_("Hello World").lines().length, 1); - equals(_(123).lines().length, 1); - }); - - test('String: pad', function() { - equals(_("1").pad(8), ' 1'); - equals(_(1).pad(8), ' 1'); - equals(_("1").pad(8, '0'), '00000001'); - equals(_("1").pad(8, '0', 'left'), '00000001'); - equals(_("1").pad(8, '0', 'right'), '10000000'); - equals(_("1").pad(8, '0', 'both'), '00001000'); - equals(_("foo").pad(8, '0', 'both'), '000foo00'); - equals(_("foo").pad(7, '0', 'both'), '00foo00'); - equals(_("foo").pad(7, '!@$%dofjrofj', 'both'), '!!foo!!'); - }); - - test('String: lpad', function() { - equals(_("1").lpad(8), ' 1'); - equals(_(1).lpad(8), ' 1'); - equals(_("1").lpad(8, '0'), '00000001'); - equals(_("1").lpad(8, '0', 'left'), '00000001'); - }); - - test('String: rpad', function() { - equals(_("1").rpad(8), '1 '); - equals(_(1).lpad(8), ' 1'); - equals(_("1").rpad(8, '0'), '10000000'); - equals(_("foo").rpad(8, '0'), 'foo00000'); - equals(_("foo").rpad(7, '0'), 'foo0000'); - }); - - test('String: lrpad', function() { - equals(_("1").lrpad(8), ' 1 '); - equals(_(1).lrpad(8), ' 1 '); - equals(_("1").lrpad(8, '0'), '00001000'); - equals(_("foo").lrpad(8, '0'), '000foo00'); - equals(_("foo").lrpad(7, '0'), '00foo00'); - equals(_("foo").lrpad(7, '!@$%dofjrofj'), '!!foo!!'); - }); - - test('String: toNumber', function() { - deepEqual(_("not a number").toNumber(), Number.NaN); - equals(_(0).toNumber(), 0); - equals(_("0").toNumber(), 0); - equals(_("0000").toNumber(), 0); - equals(_("2.345").toNumber(), 2); - equals(_("2.345").toNumber(NaN), 2); - equals(_("2.345").toNumber(2), 2.35); - equals(_("2.344").toNumber(2), 2.34); - equals(_("2").toNumber(2), 2.00); - equals(_(2).toNumber(2), 2.00); - equals(_(-2).toNumber(), -2); - equals(_("-2").toNumber(), -2); - }); - - test('String: strRight', function() { - equals(_("This_is_a_test_string").strRight("_"), "is_a_test_string"); - equals(_("This_is_a_test_string").strRight("string"), ""); - equals(_("This_is_a_test_string").strRight(), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strRight(""), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strRight("-"), "This_is_a_test_string"); - equals(_(12345).strRight(2), "345"); - }); - - test('String: strRightBack', function() { - equals(_("This_is_a_test_string").strRightBack("_"), "string"); - equals(_("This_is_a_test_string").strRightBack("string"), ""); - equals(_("This_is_a_test_string").strRightBack(), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strRightBack(""), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strRightBack("-"), "This_is_a_test_string"); - equals(_(12345).strRightBack(2), "345"); - }); - - test('String: strLeft', function() { - equals(_("This_is_a_test_string").strLeft("_"), "This"); - equals(_("This_is_a_test_string").strLeft("This"), ""); - equals(_("This_is_a_test_string").strLeft(), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strLeft(""), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strLeft("-"), "This_is_a_test_string"); - equals(_(123454321).strLeft(3), "12"); - }); - - test('String: strLeftBack', function() { - equals(_("This_is_a_test_string").strLeftBack("_"), "This_is_a_test"); - equals(_("This_is_a_test_string").strLeftBack("This"), ""); - equals(_("This_is_a_test_string").strLeftBack(), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strLeftBack(""), "This_is_a_test_string"); - equals(_("This_is_a_test_string").strLeftBack("-"), "This_is_a_test_string"); - equals(_(123454321).strLeftBack(3), "123454"); - }); - - test('Strings: stripTags', function() { - equals(_('a link').stripTags(), 'a link'); - equals(_('a link - - - - - - - - -

            Underscore.string Test Suite

            -

            -

            -
              -
              -

              Underscore.string Speed Suite

              - -
              - - diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_standalone.html b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_standalone.html deleted file mode 100644 index 9854c171..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_standalone.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - Underscore.strings Test Suite - - - - - - - - -

              Underscore.string Test Suite

              -

              -

              -
                - - diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/arrays.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/arrays.js deleted file mode 100644 index b3b1ce15..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/arrays.js +++ /dev/null @@ -1,166 +0,0 @@ -$(document).ready(function() { - - module("Arrays"); - - test("arrays: first", function() { - equals(_.first([1,2,3]), 1, 'can pull out the first element of an array'); - equals(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); - equals(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); - equals(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); - equals(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); - var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); - equals(result, 4, 'works on an arguments object.'); - result = _.map([[1,2,3],[1,2,3]], _.first); - equals(result.join(','), '1,1', 'works well with _.map'); - }); - - test("arrays: rest", function() { - var numbers = [1, 2, 3, 4]; - equals(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); - equals(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); - equals(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); - var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); - equals(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.rest); - equals(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); - }); - - test("arrays: initial", function() { - equals(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); - equals(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); - var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); - equals(result.join(", "), "1, 2, 3", 'initial works on arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.initial); - equals(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); - }); - - test("arrays: last", function() { - equals(_.last([1,2,3]), 3, 'can pull out the last element of an array'); - equals(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); - equals(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); - equals(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); - var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); - equals(result, 4, 'works on an arguments object'); - result = _.map([[1,2,3],[1,2,3]], _.last); - equals(result.join(','), '3,3', 'works well with _.map'); - }); - - test("arrays: compact", function() { - equals(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); - var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); - equals(result, 3, 'works on an arguments object'); - }); - - test("arrays: flatten", function() { - if (window.JSON) { - var list = [1, [2], [3, [[[4]]]]]; - equals(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); - equals(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); - var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); - equals(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); - } - }); - - test("arrays: without", function() { - var list = [1, 2, 1, 0, 3, 1, 4]; - equals(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); - var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); - equals(result.join(', '), '2, 3, 4', 'works on an arguments object'); - - var list = [{one : 1}, {two : 2}]; - ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); - ok(_.without(list, list[0]).length == 1, 'ditto.'); - }); - - test("arrays: uniq", function() { - var list = [1, 2, 1, 3, 1, 4]; - equals(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); - - var list = [1, 1, 1, 2, 2, 3]; - equals(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); - - var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; - var iterator = function(value) { return value.name; }; - equals(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); - - var iterator = function(value) { return value +1; }; - var list = [1, 2, 2, 3, 4, 4]; - equals(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); - - var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); - equals(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); - }); - - test("arrays: intersection", function() { - var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; - equals(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); - equals(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); - var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); - equals(result.join(''), 'moe', 'works on an arguments object'); - }); - - test("arrays: union", function() { - var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); - equals(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); - - var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); - equals(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); - }); - - test("arrays: difference", function() { - var result = _.difference([1, 2, 3], [2, 30, 40]); - equals(result.join(' '), '1 3', 'takes the difference of two arrays'); - - var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); - equals(result.join(' '), '3 4', 'takes the difference of three arrays'); - }); - - test('arrays: zip', function() { - var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; - var stooges = _.zip(names, ages, leaders); - equals(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); - }); - - test("arrays: indexOf", function() { - var numbers = [1, 2, 3]; - numbers.indexOf = null; - equals(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); - var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); - equals(result, 1, 'works on an arguments object'); - equals(_.indexOf(null, 2), -1, 'handles nulls properly'); - - var numbers = [10, 20, 30, 40, 50], num = 35; - var index = _.indexOf(numbers, num, true); - equals(index, -1, '35 is not in the list'); - - numbers = [10, 20, 30, 40, 50]; num = 40; - index = _.indexOf(numbers, num, true); - equals(index, 3, '40 is in the list'); - - numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; - index = _.indexOf(numbers, num, true); - equals(index, 1, '40 is in the list'); - }); - - test("arrays: lastIndexOf", function() { - var numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; - numbers.lastIndexOf = null; - equals(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); - equals(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); - var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); - equals(result, 5, 'works on an arguments object'); - equals(_.indexOf(null, 2), -1, 'handles nulls properly'); - }); - - test("arrays: range", function() { - equals(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); - equals(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); - equals(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); - equals(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); - equals(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); - equals(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); - equals(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); - equals(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/chaining.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/chaining.js deleted file mode 100644 index 0e3d5f38..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/chaining.js +++ /dev/null @@ -1,59 +0,0 @@ -$(document).ready(function() { - - module("Chaining"); - - test("chaining: map/flatten/reduce", function() { - var lyrics = [ - "I'm a lumberjack and I'm okay", - "I sleep all night and I work all day", - "He's a lumberjack and he's okay", - "He sleeps all night and he works all day" - ]; - var counts = _(lyrics).chain() - .map(function(line) { return line.split(''); }) - .flatten() - .reduce(function(hash, l) { - hash[l] = hash[l] || 0; - hash[l]++; - return hash; - }, {}).value(); - ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); - }); - - test("chaining: select/reject/sortBy", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; - numbers = _(numbers).chain().select(function(n) { - return n % 2 == 0; - }).reject(function(n) { - return n % 4 == 0; - }).sortBy(function(n) { - return -n; - }).value(); - equals(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); - }); - - test("chaining: select/reject/sortBy in functional style", function() { - var numbers = [1,2,3,4,5,6,7,8,9,10]; - numbers = _.chain(numbers).select(function(n) { - return n % 2 == 0; - }).reject(function(n) { - return n % 4 == 0; - }).sortBy(function(n) { - return -n; - }).value(); - equals(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); - }); - - test("chaining: reverse/concat/unshift/pop/map", function() { - var numbers = [1,2,3,4,5]; - numbers = _(numbers).chain() - .reverse() - .concat([5, 5, 5]) - .unshift(17) - .pop() - .map(function(n){ return n * 2; }) - .value(); - equals(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/collections.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/collections.js deleted file mode 100644 index cff9763c..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/collections.js +++ /dev/null @@ -1,270 +0,0 @@ -$(document).ready(function() { - - module("Collections"); - - test("collections: each", function() { - _.each([1, 2, 3], function(num, i) { - equals(num, i + 1, 'each iterators provide value and iteration count'); - }); - - var answers = []; - _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); - equals(answers.join(', '), '5, 10, 15', 'context object property accessed'); - - answers = []; - _.forEach([1, 2, 3], function(num){ answers.push(num); }); - equals(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); - - answers = []; - var obj = {one : 1, two : 2, three : 3}; - obj.constructor.prototype.four = 4; - _.each(obj, function(value, key){ answers.push(key); }); - equals(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); - delete obj.constructor.prototype.four; - - answer = null; - _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); - ok(answer, 'can reference the original collection from inside the iterator'); - - answers = 0; - _.each(null, function(){ ++answers; }); - equals(answers, 0, 'handles a null properly'); - }); - - test('collections: map', function() { - var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); - equals(doubled.join(', '), '2, 4, 6', 'doubled numbers'); - - doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); - equals(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); - - var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); - equals(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); - - var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); - equals(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); - - var ids = _.map($('div.underscore-test').children(), function(n){ return n.id; }); - ok(_.include(ids, 'qunit-header'), 'can use collection methods on NodeLists'); - - var ids = _.map(document.images, function(n){ return n.id; }); - ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); - - var ifnull = _.map(null, function(){}); - ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); - - var length = _.map(Array(2), function(v) { return v; }).length; - equals(length, 2, "can preserve a sparse array's length"); - }); - - test('collections: reduce', function() { - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equals(sum, 6, 'can sum up an array'); - - var context = {multiplier : 3}; - sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); - equals(sum, 18, 'can reduce with a context object'); - - sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); - equals(sum, 6, 'aliased as "inject"'); - - sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); - equals(sum, 6, 'OO-style reduce'); - - var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); - equals(sum, 6, 'default initial value'); - - var ifnull; - try { - _.reduce(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); - - ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - equals(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); - - var sparseArray = []; - sparseArray[0] = 20; - sparseArray[2] = -5; - equals(_.reduce(sparseArray, function(a, b){ return a - b; }), 25, 'initially-sparse arrays with no memo'); - }); - - test('collections: reduceRight', function() { - var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equals(list, 'bazbarfoo', 'can perform right folds'); - - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); - equals(list, 'bazbarfoo', 'aliased as "foldr"'); - - var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); - equals(list, 'bazbarfoo', 'default initial value'); - - var ifnull; - try { - _.reduceRight(null, function(){}); - } catch (ex) { - ifnull = ex; - } - ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); - - ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); - - equals(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); - raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); - - var sparseArray = []; - sparseArray[0] = 20; - sparseArray[2] = -5; - equals(_.reduceRight(sparseArray, function(a, b){ return a - b; }), -25, 'initially-sparse arrays with no memo'); - }); - - test('collections: detect', function() { - var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); - equals(result, 2, 'found the first "2" and broke the loop'); - }); - - test('collections: select', function() { - var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equals(evens.join(', '), '2, 4, 6', 'selected each even number'); - - evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equals(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); - }); - - test('collections: reject', function() { - var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); - equals(odds.join(', '), '1, 3, 5', 'rejected each even number'); - }); - - test('collections: all', function() { - ok(_.all([], _.identity), 'the empty set'); - ok(_.all([true, true, true], _.identity), 'all true values'); - ok(!_.all([true, false, true], _.identity), 'one false value'); - ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); - ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); - ok(_.every([true, true, true], _.identity), 'aliased as "every"'); - }); - - test('collections: any', function() { - var nativeSome = Array.prototype.some; - Array.prototype.some = null; - ok(!_.any([]), 'the empty set'); - ok(!_.any([false, false, false]), 'all false values'); - ok(_.any([false, false, true]), 'one true value'); - ok(_.any([null, 0, 'yes', false]), 'a string'); - ok(!_.any([null, 0, '', false]), 'falsy values'); - ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); - ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); - ok(_.some([false, false, true]), 'aliased as "some"'); - Array.prototype.some = nativeSome; - }); - - test('collections: include', function() { - ok(_.include([1,2,3], 2), 'two is in the array'); - ok(!_.include([1,3,9], 2), 'two is not in the array'); - ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); - ok(_([1,2,3]).include(2), 'OO-style include'); - }); - - test('collections: invoke', function() { - var list = [[5, 1, 7], [3, 2, 1]]; - var result = _.invoke(list, 'sort'); - equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); - }); - - test('collections: invoke w/ function reference', function() { - var list = [[5, 1, 7], [3, 2, 1]]; - var result = _.invoke(list, Array.prototype.sort); - equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); - }); - - // Relevant when using ClojureScript - test('collections: invoke when strings have a call method', function() { - String.prototype.call = function(){return 42;} - var list = [[5, 1, 7], [3, 2, 1]]; - var s = "foo"; - equals(s.call(), 42, "call function exists"); - var result = _.invoke(list, 'sort'); - equals(result[0].join(', '), '1, 5, 7', 'first array sorted'); - equals(result[1].join(', '), '1, 2, 3', 'second array sorted'); - delete String.prototype.call; - equals(s.call, undefined, "call function removed"); - }); - - test('collections: pluck', function() { - var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; - equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); - }); - - test('collections: max', function() { - equals(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); - - var neg = _.max([1, 2, 3], function(num){ return -num; }); - equals(neg, 1, 'can perform a computation-based max'); - - equals(-Infinity, _.max({}), 'Maximum value of an empty object'); - equals(-Infinity, _.max([]), 'Maximum value of an empty array'); - }); - - test('collections: min', function() { - equals(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); - - var neg = _.min([1, 2, 3], function(num){ return -num; }); - equals(neg, 3, 'can perform a computation-based min'); - - equals(Infinity, _.min({}), 'Minimum value of an empty object'); - equals(Infinity, _.min([]), 'Minimum value of an empty array'); - }); - - test('collections: sortBy', function() { - var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; - people = _.sortBy(people, function(person){ return person.age; }); - equals(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); - }); - - test('collections: groupBy', function() { - var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); - ok('0' in parity && '1' in parity, 'created a group for each value'); - equals(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); - - var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; - var grouped = _.groupBy(list, 'length'); - equals(grouped['3'].join(' '), 'one two six ten'); - equals(grouped['4'].join(' '), 'four five nine'); - equals(grouped['5'].join(' '), 'three seven eight'); - }); - - test('collections: sortedIndex', function() { - var numbers = [10, 20, 30, 40, 50], num = 35; - var index = _.sortedIndex(numbers, num); - equals(index, 3, '35 should be inserted at index 3'); - }); - - test('collections: shuffle', function() { - var numbers = _.range(10); - var shuffled = _.shuffle(numbers).sort(); - notStrictEqual(numbers, shuffled, 'original object is unmodified'); - equals(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); - }); - - test('collections: toArray', function() { - ok(!_.isArray(arguments), 'arguments object is not an array'); - ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); - var a = [1,2,3]; - ok(_.toArray(a) !== a, 'array is cloned'); - equals(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); - - var numbers = _.toArray({one : 1, two : 2, three : 3}); - equals(numbers.join(', '), '1, 2, 3', 'object flattened into array'); - }); - - test('collections: size', function() { - equals(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/functions.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/functions.js deleted file mode 100644 index 78721af1..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/functions.js +++ /dev/null @@ -1,198 +0,0 @@ -$(document).ready(function() { - - module("Functions"); - - test("functions: bind", function() { - var context = {name : 'moe'}; - var func = function(arg) { return "name: " + (this.name || arg); }; - var bound = _.bind(func, context); - equals(bound(), 'name: moe', 'can bind a function to a context'); - - bound = _(func).bind(context); - equals(bound(), 'name: moe', 'can do OO-style binding'); - - bound = _.bind(func, null, 'curly'); - equals(bound(), 'name: curly', 'can bind without specifying a context'); - - func = function(salutation, name) { return salutation + ': ' + name; }; - func = _.bind(func, this, 'hello'); - equals(func('moe'), 'hello: moe', 'the function was partially applied in advance'); - - var func = _.bind(func, this, 'curly'); - equals(func(), 'hello: curly', 'the function was completely applied in advance'); - - var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; - func = _.bind(func, this, 'hello', 'moe', 'curly'); - equals(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); - - func = function(context, message) { equals(this, context, message); }; - _.bind(func, 0, 0, 'can bind a function to `0`')(); - _.bind(func, '', '', 'can bind a function to an empty string')(); - _.bind(func, false, false, 'can bind a function to `false`')(); - - // These tests are only meaningful when using a browser without a native bind function - // To test this with a modern browser, set underscore's nativeBind to undefined - var F = function () { return this; }; - var Boundf = _.bind(F, {hello: "moe curly"}); - equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); - equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); - }); - - test("functions: bindAll", function() { - var curly = {name : 'curly'}, moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } - }; - curly.getName = moe.getName; - _.bindAll(moe, 'getName', 'sayHi'); - curly.sayHi = moe.sayHi; - equals(curly.getName(), 'name: curly', 'unbound function is bound to current object'); - equals(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); - - curly = {name : 'curly'}; - moe = { - name : 'moe', - getName : function() { return 'name: ' + this.name; }, - sayHi : function() { return 'hi: ' + this.name; } - }; - _.bindAll(moe); - curly.sayHi = moe.sayHi; - equals(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); - }); - - test("functions: memoize", function() { - var fib = function(n) { - return n < 2 ? n : fib(n - 1) + fib(n - 2); - }; - var fastFib = _.memoize(fib); - equals(fib(10), 55, 'a memoized version of fibonacci produces identical results'); - equals(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); - - var o = function(str) { - return str; - }; - var fastO = _.memoize(o); - equals(o('toString'), 'toString', 'checks hasOwnProperty'); - equals(fastO('toString'), 'toString', 'checks hasOwnProperty'); - }); - - asyncTest("functions: delay", 2, function() { - var delayed = false; - _.delay(function(){ delayed = true; }, 100); - setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); - setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); - }); - - asyncTest("functions: defer", 1, function() { - var deferred = false; - _.defer(function(bool){ deferred = bool; }, true); - _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); - }); - - asyncTest("functions: throttle", 2, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); throttledIncr(); throttledIncr(); - setTimeout(throttledIncr, 70); - setTimeout(throttledIncr, 120); - setTimeout(throttledIncr, 140); - setTimeout(throttledIncr, 190); - setTimeout(throttledIncr, 220); - setTimeout(throttledIncr, 240); - _.delay(function(){ ok(counter == 1, "incr was called immediately"); }, 30); - _.delay(function(){ ok(counter == 4, "incr was throttled"); start(); }, 400); - }); - - asyncTest("functions: throttle arguments", 2, function() { - var value = 0; - var update = function(val){ value = val; }; - var throttledUpdate = _.throttle(update, 100); - throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); - setTimeout(function(){ throttledUpdate(4); }, 120); - setTimeout(function(){ throttledUpdate(5); }, 140); - setTimeout(function(){ throttledUpdate(6); }, 250); - _.delay(function(){ equals(value, 1, "updated to latest value"); }, 40); - _.delay(function(){ equals(value, 6, "updated to latest value"); start(); }, 400); - }); - - asyncTest("functions: throttle once", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); - _.delay(function(){ ok(counter == 1, "incr was called once"); start(); }, 220); - }); - - asyncTest("functions: throttle twice", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var throttledIncr = _.throttle(incr, 100); - throttledIncr(); throttledIncr(); - _.delay(function(){ ok(counter == 2, "incr was called twice"); start(); }, 220); - }); - - asyncTest("functions: debounce", 1, function() { - var counter = 0; - var incr = function(){ counter++; }; - var debouncedIncr = _.debounce(incr, 50); - debouncedIncr(); debouncedIncr(); debouncedIncr(); - setTimeout(debouncedIncr, 30); - setTimeout(debouncedIncr, 60); - setTimeout(debouncedIncr, 90); - setTimeout(debouncedIncr, 120); - setTimeout(debouncedIncr, 150); - _.delay(function(){ ok(counter == 1, "incr was debounced"); start(); }, 220); - }); - - test("functions: once", function() { - var num = 0; - var increment = _.once(function(){ num++; }); - increment(); - increment(); - equals(num, 1); - }); - - test("functions: wrap", function() { - var greet = function(name){ return "hi: " + name; }; - var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); - equals(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); - - var inner = function(){ return "Hello "; }; - var obj = {name : "Moe"}; - obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); - equals(obj.hi(), "Hello Moe"); - - var noop = function(){}; - var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); - var ret = wrapped(['whats', 'your'], 'vector', 'victor'); - same(ret, [noop, ['whats', 'your'], 'vector', 'victor']); - }); - - test("functions: compose", function() { - var greet = function(name){ return "hi: " + name; }; - var exclaim = function(sentence){ return sentence + '!'; }; - var composed = _.compose(exclaim, greet); - equals(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); - - composed = _.compose(greet, exclaim); - equals(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); - }); - - test("functions: after", function() { - var testAfter = function(afterAmount, timesCalled) { - var afterCalled = 0; - var after = _.after(afterAmount, function() { - afterCalled++; - }); - while (timesCalled--) after(); - return afterCalled; - }; - - equals(testAfter(5, 5), 1, "after(N) should fire after being called N times"); - equals(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); - equals(testAfter(0, 0), 1, "after(0) should fire immediately"); - }); - -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/objects.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/objects.js deleted file mode 100644 index 0105d608..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/objects.js +++ /dev/null @@ -1,535 +0,0 @@ -$(document).ready(function() { - - module("Objects"); - - test("objects: keys", function() { - var exception = /object/; - equals(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); - // the test above is not safe because it relies on for-in enumeration order - var a = []; a[1] = 0; - equals(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); - raises(function() { _.keys(null); }, exception, 'throws an error for `null` values'); - raises(function() { _.keys(void 0); }, exception, 'throws an error for `undefined` values'); - raises(function() { _.keys(1); }, exception, 'throws an error for number primitives'); - raises(function() { _.keys('a'); }, exception, 'throws an error for string primitives'); - raises(function() { _.keys(true); }, exception, 'throws an error for boolean primitives'); - }); - - test("objects: values", function() { - equals(_.values({one : 1, two : 2}).join(', '), '1, 2', 'can extract the values from an object'); - }); - - test("objects: functions", function() { - var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; - ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); - - var Animal = function(){}; - Animal.prototype.run = function(){}; - equals(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); - }); - - test("objects: extend", function() { - var result; - equals(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); - equals(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); - equals(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); - result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); - ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); - result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); - ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); - result = _.extend({}, {a: void 0, b: null}); - equals(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); - }); - - test("objects: defaults", function() { - var result; - var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; - - _.defaults(options, {zero: 1, one: 10, twenty: 20}); - equals(options.zero, 0, 'value exists'); - equals(options.one, 1, 'value exists'); - equals(options.twenty, 20, 'default applied'); - - _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); - equals(options.empty, "", 'value exists'); - ok(_.isNaN(options.nan), "NaN isn't overridden"); - equals(options.word, "word", 'new value is added, first one wins'); - }); - - test("objects: clone", function() { - var moe = {name : 'moe', lucky : [13, 27, 34]}; - var clone = _.clone(moe); - equals(clone.name, 'moe', 'the clone as the attributes of the original'); - - clone.name = 'curly'; - ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); - - clone.lucky.push(101); - equals(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); - - equals(_.clone(undefined), void 0, 'non objects should not be changed by clone'); - equals(_.clone(1), 1, 'non objects should not be changed by clone'); - equals(_.clone(null), null, 'non objects should not be changed by clone'); - }); - - test("objects: isEqual", function() { - function First() { - this.value = 1; - } - First.prototype.value = 1; - function Second() { - this.value = 1; - } - Second.prototype.value = 2; - - // Basic equality and identity comparisons. - ok(_.isEqual(null, null), "`null` is equal to `null`"); - ok(_.isEqual(), "`undefined` is equal to `undefined`"); - - ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); - ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); - ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); - ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); - - // String object and primitive comparisons. - ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); - ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); - ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); - ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); - - ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); - ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); - ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); - - // Number object and primitive comparisons. - ok(_.isEqual(75, 75), "Identical number primitives are equal"); - ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); - ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); - ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); - ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); - - ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); - ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); - - // Comparisons involving `NaN`. - ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); - ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); - ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); - ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); - - // Boolean object and primitive comparisons. - ok(_.isEqual(true, true), "Identical boolean primitives are equal"); - ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); - ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); - ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); - ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); - - // Common type coercions. - ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); - ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); - ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); - ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); - ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); - ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); - ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); - ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); - ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); - - // Dates. - ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); - ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); - ok(!_.isEqual(new Date(2009, 11, 13), { - getTime: function(){ - return 12606876e5; - } - }), "Date objects and objects with a `getTime` method are not equal"); - ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); - - // Functions. - ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); - - // RegExps. - ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); - ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); - ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); - ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); - ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); - - // Empty arrays, array-like objects, and object literals. - ok(_.isEqual({}, {}), "Empty object literals are equal"); - ok(_.isEqual([], []), "Empty array literals are equal"); - ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); - ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); - ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); - - ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); - ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); - - // Arrays with primitive and object values. - ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); - ok(_.isEqual([/Moe/g, new Date(2009, 9, 25)], [/Moe/g, new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); - - // Multi-dimensional arrays. - var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; - ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); - - // Overwrite the methods defined in ES 5.1 section 15.4.4. - a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; - b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; - - // Array elements and properties. - ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); - a.push("White Rocks"); - ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); - a.push("East Boulder"); - b.push("Gunbarrel Ranch", "Teller Farm"); - ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); - - // Sparse arrays. - ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); - ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); - - // According to the Microsoft deviations spec, section 2.1.26, JScript 5.x treats `undefined` - // elements in arrays as elisions. Thus, sparse arrays and dense arrays containing `undefined` - // values are equivalent. - if (0 in [undefined]) { - ok(!_.isEqual(Array(3), [undefined, undefined, undefined]), "Sparse and dense arrays are not equal"); - ok(!_.isEqual([undefined, undefined, undefined], Array(3)), "Commutative equality is implemented for sparse and dense arrays"); - } - - // Simple objects. - ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); - ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); - ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); - ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); - ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); - ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); - - // `A` contains nested objects and arrays. - a = { - name: new String("Moe Howard"), - age: new Number(77), - stooge: true, - hobbies: ["acting"], - film: { - name: "Sing a Song of Six Pants", - release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], - minutes: new Number(16), - seconds: 54 - } - }; - - // `B` contains equivalent nested objects and arrays. - b = { - name: new String("Moe Howard"), - age: new Number(77), - stooge: true, - hobbies: ["acting"], - film: { - name: "Sing a Song of Six Pants", - release: new Date(1947, 9, 30), - stars: [new String("Larry Fine"), "Shemp Howard"], - minutes: new Number(16), - seconds: 54 - } - }; - ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); - - // Instances. - ok(_.isEqual(new First, new First), "Object instances are equal"); - ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); - ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); - ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); - - // Circular Arrays. - (a = []).push(a); - (b = []).push(b); - ok(_.isEqual(a, b), "Arrays containing circular references are equal"); - a.push(new String("Larry")); - b.push(new String("Larry")); - ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); - a.push("Shemp"); - b.push("Curly"); - ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); - - // Circular Objects. - a = {abc: null}; - b = {abc: null}; - a.abc = a; - b.abc = b; - ok(_.isEqual(a, b), "Objects containing circular references are equal"); - a.def = 75; - b.def = 75; - ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); - a.def = new Number(75); - b.def = new Number(63); - ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); - - // Cyclic Structures. - a = [{abc: null}]; - b = [{abc: null}]; - (a[0].abc = a).push(a); - (b[0].abc = b).push(b); - ok(_.isEqual(a, b), "Cyclic structures are equal"); - a[0].def = "Larry"; - b[0].def = "Larry"; - ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); - a[0].def = new String("Larry"); - b[0].def = new String("Curly"); - ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); - - // Complex Circular References. - a = {foo: {b: {foo: {c: {foo: null}}}}}; - b = {foo: {b: {foo: {c: {foo: null}}}}}; - a.foo.b.foo.c.foo = a; - b.foo.b.foo.c.foo = b; - ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); - - // Chaining. - ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); - equals(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); - - // Custom `isEqual` methods. - var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; - var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; - - ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); - ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); - ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); - ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); - - // Custom `isEqual` methods - comparing different types - LocalizedString = (function() { - function LocalizedString(id) { this.id = id; this.string = (this.id===10)? 'Bonjour': ''; } - LocalizedString.prototype.isEqual = function(that) { - if (_.isString(that)) return this.string == that; - else if (that instanceof LocalizedString) return this.id == that.id; - return false; - }; - return LocalizedString; - })(); - var localized_string1 = new LocalizedString(10), localized_string2 = new LocalizedString(10), localized_string3 = new LocalizedString(11); - ok(_.isEqual(localized_string1, localized_string2), 'comparing same typed instances with same ids'); - ok(!_.isEqual(localized_string1, localized_string3), 'comparing same typed instances with different ids'); - ok(_.isEqual(localized_string1, 'Bonjour'), 'comparing different typed instances with same values'); - ok(_.isEqual('Bonjour', localized_string1), 'comparing different typed instances with same values'); - ok(!_.isEqual('Bonjour', localized_string3), 'comparing two localized strings with different ids'); - ok(!_.isEqual(localized_string1, 'Au revoir'), 'comparing different typed instances with different values'); - ok(!_.isEqual('Au revoir', localized_string1), 'comparing different typed instances with different values'); - - // Custom `isEqual` methods - comparing with serialized data - Date.prototype.toJSON = function() { - return { - _type:'Date', - year:this.getUTCFullYear(), - month:this.getUTCMonth(), - day:this.getUTCDate(), - hours:this.getUTCHours(), - minutes:this.getUTCMinutes(), - seconds:this.getUTCSeconds() - }; - }; - Date.prototype.isEqual = function(that) { - var this_date_components = this.toJSON(); - var that_date_components = (that instanceof Date) ? that.toJSON() : that; - delete this_date_components['_type']; delete that_date_components['_type'] - return _.isEqual(this_date_components, that_date_components); - }; - - var date = new Date(); - var date_json = { - _type:'Date', - year:date.getUTCFullYear(), - month:date.getUTCMonth(), - day:date.getUTCDate(), - hours:date.getUTCHours(), - minutes:date.getUTCMinutes(), - seconds:date.getUTCSeconds() - }; - - ok(_.isEqual(date_json, date), 'serialized date matches date'); - ok(_.isEqual(date, date_json), 'date matches serialized date'); - }); - - test("objects: isEmpty", function() { - ok(!_([1]).isEmpty(), '[1] is not empty'); - ok(_.isEmpty([]), '[] is empty'); - ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); - ok(_.isEmpty({}), '{} is empty'); - ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); - ok(_.isEmpty(null), 'null is empty'); - ok(_.isEmpty(), 'undefined is empty'); - ok(_.isEmpty(''), 'the empty string is empty'); - ok(!_.isEmpty('moe'), 'but other strings are not'); - - var obj = {one : 1}; - delete obj.one; - ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); - }); - - // Setup remote variables for iFrame tests. - var iframe = document.createElement('iframe'); - jQuery(iframe).appendTo(document.body); - var iDoc = iframe.contentDocument || iframe.contentWindow.document; - iDoc.write( - "" - ); - iDoc.close(); - - test("objects: isElement", function() { - ok(!_.isElement('div'), 'strings are not dom elements'); - ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); - ok(_.isElement(iElement), 'even from another frame'); - }); - - test("objects: isArguments", function() { - var args = (function(){ return arguments; })(1, 2, 3); - ok(!_.isArguments('string'), 'a string is not an arguments object'); - ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); - ok(_.isArguments(args), 'but the arguments object is an arguments object'); - ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); - ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); - ok(_.isArguments(iArguments), 'even from another frame'); - }); - - test("objects: isObject", function() { - ok(_.isObject(arguments), 'the arguments object is object'); - ok(_.isObject([1, 2, 3]), 'and arrays'); - ok(_.isObject($('html')[0]), 'and DOM element'); - ok(_.isObject(iElement), 'even from another frame'); - ok(_.isObject(function () {}), 'and functions'); - ok(_.isObject(iFunction), 'even from another frame'); - ok(!_.isObject(null), 'but not null'); - ok(!_.isObject(undefined), 'and not undefined'); - ok(!_.isObject('string'), 'and not string'); - ok(!_.isObject(12), 'and not number'); - ok(!_.isObject(true), 'and not boolean'); - ok(_.isObject(new String('string')), 'but new String()'); - }); - - test("objects: isArray", function() { - ok(!_.isArray(arguments), 'the arguments object is not an array'); - ok(_.isArray([1, 2, 3]), 'but arrays are'); - ok(_.isArray(iArray), 'even from another frame'); - }); - - test("objects: isString", function() { - ok(!_.isString(document.body), 'the document body is not a string'); - ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); - ok(_.isString(iString), 'even from another frame'); - }); - - test("objects: isNumber", function() { - ok(!_.isNumber('string'), 'a string is not a number'); - ok(!_.isNumber(arguments), 'the arguments object is not a number'); - ok(!_.isNumber(undefined), 'undefined is not a number'); - ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); - ok(_.isNumber(NaN), 'NaN *is* a number'); - ok(_.isNumber(Infinity), 'Infinity is a number'); - ok(_.isNumber(iNumber), 'even from another frame'); - ok(!_.isNumber('1'), 'numeric strings are not numbers'); - }); - - test("objects: isBoolean", function() { - ok(!_.isBoolean(2), 'a number is not a boolean'); - ok(!_.isBoolean("string"), 'a string is not a boolean'); - ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); - ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); - ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); - ok(!_.isBoolean(undefined), 'undefined is not a boolean'); - ok(!_.isBoolean(NaN), 'NaN is not a boolean'); - ok(!_.isBoolean(null), 'null is not a boolean'); - ok(_.isBoolean(true), 'but true is'); - ok(_.isBoolean(false), 'and so is false'); - ok(_.isBoolean(iBoolean), 'even from another frame'); - }); - - test("objects: isFunction", function() { - ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); - ok(!_.isFunction('moe'), 'strings are not functions'); - ok(_.isFunction(_.isFunction), 'but functions are'); - ok(_.isFunction(iFunction), 'even from another frame'); - }); - - test("objects: isDate", function() { - ok(!_.isDate(100), 'numbers are not dates'); - ok(!_.isDate({}), 'objects are not dates'); - ok(_.isDate(new Date()), 'but dates are'); - ok(_.isDate(iDate), 'even from another frame'); - }); - - test("objects: isRegExp", function() { - ok(!_.isRegExp(_.identity), 'functions are not RegExps'); - ok(_.isRegExp(/identity/), 'but RegExps are'); - ok(_.isRegExp(iRegExp), 'even from another frame'); - }); - - test("objects: isNaN", function() { - ok(!_.isNaN(undefined), 'undefined is not NaN'); - ok(!_.isNaN(null), 'null is not NaN'); - ok(!_.isNaN(0), '0 is not NaN'); - ok(_.isNaN(NaN), 'but NaN is'); - ok(_.isNaN(iNaN), 'even from another frame'); - }); - - test("objects: isNull", function() { - ok(!_.isNull(undefined), 'undefined is not null'); - ok(!_.isNull(NaN), 'NaN is not null'); - ok(_.isNull(null), 'but null is'); - ok(_.isNull(iNull), 'even from another frame'); - }); - - test("objects: isUndefined", function() { - ok(!_.isUndefined(1), 'numbers are defined'); - ok(!_.isUndefined(null), 'null is defined'); - ok(!_.isUndefined(false), 'false is defined'); - ok(!_.isUndefined(NaN), 'NaN is defined'); - ok(_.isUndefined(), 'nothing is undefined'); - ok(_.isUndefined(undefined), 'undefined is undefined'); - ok(_.isUndefined(iUndefined), 'even from another frame'); - }); - - if (window.ActiveXObject) { - test("objects: IE host objects", function() { - var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); - ok(!_.isNumber(xml)); - ok(!_.isBoolean(xml)); - ok(!_.isNaN(xml)); - ok(!_.isFunction(xml)); - ok(!_.isNull(xml)); - ok(!_.isUndefined(xml)); - }); - } - - test("objects: tap", function() { - var intercepted = null; - var interceptor = function(obj) { intercepted = obj; }; - var returned = _.tap(1, interceptor); - equals(intercepted, 1, "passes tapped object to interceptor"); - equals(returned, 1, "returns tapped object"); - - returned = _([1,2,3]).chain(). - map(function(n){ return n * 2; }). - max(). - tap(interceptor). - value(); - ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); - }); -}); diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/speed.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/speed.js deleted file mode 100644 index 86663a23..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/speed.js +++ /dev/null @@ -1,70 +0,0 @@ -(function() { - - var numbers = []; - for (var i=0; i<1000; i++) numbers.push(i); - var objects = _.map(numbers, function(n){ return {num : n}; }); - var randomized = _.sortBy(numbers, function(){ return Math.random(); }); - - JSLitmus.test('_.each()', function() { - var timesTwo = []; - _.each(numbers, function(num){ timesTwo.push(num * 2); }); - return timesTwo; - }); - - JSLitmus.test('_(list).each()', function() { - var timesTwo = []; - _(numbers).each(function(num){ timesTwo.push(num * 2); }); - return timesTwo; - }); - - JSLitmus.test('jQuery.each()', function() { - var timesTwo = []; - jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); - return timesTwo; - }); - - JSLitmus.test('_.map()', function() { - return _.map(objects, function(obj){ return obj.num; }); - }); - - JSLitmus.test('jQuery.map()', function() { - return jQuery.map(objects, function(obj){ return obj.num; }); - }); - - JSLitmus.test('_.pluck()', function() { - return _.pluck(objects, 'num'); - }); - - JSLitmus.test('_.uniq()', function() { - return _.uniq(randomized); - }); - - JSLitmus.test('_.uniq() (sorted)', function() { - return _.uniq(numbers, true); - }); - - JSLitmus.test('_.sortBy()', function() { - return _.sortBy(numbers, function(num){ return -num; }); - }); - - JSLitmus.test('_.isEqual()', function() { - return _.isEqual(numbers, randomized); - }); - - JSLitmus.test('_.keys()', function() { - return _.keys(objects); - }); - - JSLitmus.test('_.values()', function() { - return _.values(objects); - }); - - JSLitmus.test('_.intersect()', function() { - return _.intersect(numbers, randomized); - }); - - JSLitmus.test('_.range()', function() { - return _.range(1000); - }); - -})(); \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp.js deleted file mode 100644 index 68c39dc5..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp.js +++ /dev/null @@ -1,27 +0,0 @@ -(function() { - - var func = function(){}; - var date = new Date(); - var str = "a string"; - var numbers = []; - for (var i=0; i<1000; i++) numbers.push(i); - var objects = _.map(numbers, function(n){ return {num : n}; }); - var randomized = _.sortBy(numbers, function(){ return Math.random(); }); - - JSLitmus.test('_.isNumber', function() { - return _.isNumber(1000) - }); - - JSLitmus.test('_.newIsNumber', function() { - return _.newIsNumber(1000) - }); - - JSLitmus.test('_.isNumber(NaN)', function() { - return _.isNumber(NaN) - }); - - JSLitmus.test('_.newIsNumber(NaN)', function() { - return _.newIsNumber(NaN) - }); - -})(); \ No newline at end of file diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp_tests.html b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp_tests.html deleted file mode 100644 index bd34f9dd..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/temp_tests.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - Underscore Temporary Tests - - - - - - - -

                Underscore Temporary Tests

                -

                - A page for temporary speed tests, used for developing faster implementations - of existing Underscore methods. -

                -
                - - diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/test.html b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/test.html deleted file mode 100644 index 77f2f3a2..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/test.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - Underscore Test Suite - - - - - - - - - - - - - - - -
                -

                Underscore Test Suite

                -

                -

                -
                  -
                  -

                  Underscore Speed Suite

                  -

                  - A representative sample of the functions are benchmarked here, to provide - a sense of how fast they might run in different browsers. - Each iteration runs on an array of 1000 elements.

                  - For example, the 'intersect' test measures the number of times you can - find the intersection of two thousand-element arrays in one second. -

                  -
                  - - -
                  - - diff --git a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/utility.js b/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/utility.js deleted file mode 100644 index 7bc5cb44..00000000 --- a/spec/fixture/node_modules/grunt/node_modules/underscore.string/test/test_underscore/utility.js +++ /dev/null @@ -1,155 +0,0 @@ -$(document).ready(function() { - - module("Utility"); - - test("utility: noConflict", function() { - var underscore = _.noConflict(); - ok(underscore.isUndefined(_), "The '_' variable has been returned to its previous state."); - var intersection = underscore.intersect([-1, 0, 1, 2], [1, 2, 3, 4]); - equals(intersection.join(', '), '1, 2', 'but the intersection function still works'); - window._ = underscore; - }); - - test("utility: identity", function() { - var moe = {name : 'moe'}; - equals(_.identity(moe), moe, 'moe is the same as his identity'); - }); - - test("utility: uniqueId", function() { - var ids = [], i = 0; - while(i++ < 100) ids.push(_.uniqueId()); - equals(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); - }); - - test("utility: times", function() { - var vals = []; - _.times(3, function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); - // - vals = []; - _(3).times(function (i) { vals.push(i); }); - ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); - }); - - test("utility: mixin", function() { - _.mixin({ - myReverse: function(string) { - return string.split('').reverse().join(''); - } - }); - equals(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); - equals(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); - }); - - test("utility: _.escape", function() { - equals(_.escape("Curly & Moe"), "Curly & Moe"); - equals(_.escape("Curly & Moe"), "Curly &amp; Moe"); - }); - - test("utility: template", function() { - var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); - var result = basicTemplate({thing : 'This'}); - equals(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); - - var sansSemicolonTemplate = _.template("A <% this %> B"); - equals(sansSemicolonTemplate(), "A B"); - - var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); - equals(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); - - var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); - equals(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); - - var fancyTemplate = _.template("
                    <% \ - for (key in people) { \ - %>
                  • <%= people[key] %>
                  • <% } %>
                  "); - result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); - equals(result, "
                  • Moe
                  • Larry
                  • Curly
                  ", 'can run arbitrary javascript in templates'); - - var escapedCharsInJavascriptTemplate = _.template("
                    <% _.each(numbers.split('\\n'), function(item) { %>
                  • <%= item %>
                  • <% }) %>
                  "); - result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); - equals(result, "
                  • one
                  • two
                  • three
                  • four
                  ", 'Can use escaped characters (e.g. \\n) in Javascript'); - - var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
                  \">
                  <% }); %>"); - result = namespaceCollisionTemplate({ - pageCount: 3, - thumbnails: { - 1: "p1-thumbnail.gif", - 2: "p2-thumbnail.gif", - 3: "p3-thumbnail.gif" - } - }); - equals(result, "3 p3-thumbnail.gif
                  "); - - var noInterpolateTemplate = _.template("

                  Just some text. Hey, I know this is silly but it aids consistency.

                  "); - result = noInterpolateTemplate(); - equals(result, "

                  Just some text. Hey, I know this is silly but it aids consistency.

                  "); - - var quoteTemplate = _.template("It's its, not it's"); - equals(quoteTemplate({}), "It's its, not it's"); - - var quoteInStatementAndBody = _.template("<%\ - if(foo == 'bar'){ \ - %>Statement quotes and 'quotes'.<% } %>"); - equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); - - var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); - equals(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); - - var template = _.template("<%- value %>"); - var result = template({value: " -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm i --save lodash - -{sudo} npm i -g lodash -npm ln lodash -``` - -In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): - -```js -var _ = require('lodash'); -// or as Underscore -var _ = require('lodash/dist/lodash.underscore'); -``` - -**Notes:** - * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL - * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader: - -```js -require({ - 'packages': [ - { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } - ] -}, -['lodash'], function(_) { - console.log(_.VERSION); -}); -``` - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 23798ba8..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,7157 +0,0 @@ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; - - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = {}; - - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; - - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; - - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; - - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + - - // line terminators - '\n\r\u2028\u2029' + - - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowedProps = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - errorClass = '[object Error]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; - - /** Used as the data object for `iteratorTemplate` */ - var iteratorData = { - 'args': '', - 'array': null, - 'bottom': '', - 'firstArg': '', - 'init': '', - 'keys': null, - 'loop': '', - 'shadowedProps': null, - 'support': null, - 'top': '', - 'useHas': false - }; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; - - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; - } - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } - - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; - - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); - - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; - } - } - } - - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; - - while (++index < length) { - var value = ac[index], - other = bc[index]; - - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; - - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; - - while (++index < length) { - result.push(array[index]); - } - return result; - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } - - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); - } - } - - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); - } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); - } - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ - var arrayRef = []; - - /** Used for native method references */ - var errorProto = Error.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; - - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); - - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; - - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to avoid iterating non-enumerable properties in IE < 9 */ - var nonEnumProps = {}; - nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; - nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; - nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; - nonEnumProps[objectClass] = { 'constructor': true }; - - (function() { - var length = shadowedProps.length; - while (length--) { - var key = shadowedProps[length]; - for (var className in nonEnumProps) { - if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { - nonEnumProps[className][key] = false; - } - } - } - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; - - /** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function() { - var ctor = function() { this.x = 1; }, - object = { '0': 1, 'length': 1 }, - props = []; - - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var key in new ctor) { props.push(key); } - for (key in arguments) { } - - /** - * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsClass = toString.call(arguments) == argsClass; - - /** - * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). - * - * @memberOf _.support - * @type boolean - */ - support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); - - /** - * Detect if `name` or `message` properties of `Error.prototype` are - * enumerable by default. (IE < 9, Safari < 5.1) - * - * @memberOf _.support - * @type boolean - */ - support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); - - /** - * Detect if `prototype` properties are enumerable by default. - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - * - * @memberOf _.support - * @type boolean - */ - support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if `arguments` object indexes are non-enumerable - * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumArgs = key != 0; - - /** - * Detect if properties shadowing those on `Object.prototype` are non-enumerable. - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumShadows = !/valueOf/.test(props); - - /** - * Detect if own properties are iterated after inherited properties (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.ownLast = props[0] != 'x'; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); - - /** - * Detect lack of support for accessing string characters by index. - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - * - * @memberOf _.support - * @type boolean - */ - support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) - * and that the JS engine errors when attempting to coerce an object to - * a string without a `toString` function. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); - } catch(e) { - support.nodeClass = true; - } - }(1)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Object} data The data object used to populate the text. - * @returns {string} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg) + - ', result = ' + - (obj.init) + - ';\nif (!iterable) return result;\n' + - (obj.top) + - ';'; - if (obj.array) { - __p += '\nvar length = iterable.length; index = -1;\nif (' + - (obj.array) + - ') { '; - if (support.unindexedChars) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } - __p += '\n while (++index < length) {\n ' + - (obj.loop) + - ';\n }\n}\nelse { '; - } else if (support.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop) + - ';\n }\n } else { '; - } - - if (support.enumPrototypes) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } - - if (support.enumErrorProps) { - __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; - } - - var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } - - if (obj.useHas && obj.keys) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; - if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - } else { - __p += '\n for (index in iterable) {\n'; - if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - if (support.nonEnumShadows) { - __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; - for (k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowedProps[k]) + - '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; - if (!obj.useHas) { - __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; - } - __p += ') {\n ' + - (obj.loop) + - ';\n } '; - } - __p += '\n } '; - } - - } - - if (obj.array || support.nonEnumArgs) { - __p += '\n}'; - } - __p += - (obj.bottom) + - ';\nreturn result'; - - return __p - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; - } - else { - result = isArr ? slice(value) : assign({}, value); - } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - // exit for shallow clone - if (!isDeep) { - return result; - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); - }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } - - /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. - */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; - - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(values); - } - return result; - } - - /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. - */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - } - stackA.pop(); - stackB.pop(); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - - /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. - * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. - */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; - - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; - - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; - } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; - } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; - } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); - } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); - } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {...Object} [options] The compile options object(s). - * @param {string} [options.array] Code to determine if the iterable is an array or array-like. - * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. - * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. - * @param {string} [options.args] A comma separated string of iteration function arguments. - * @param {string} [options.top] Code to execute before the iteration branches. - * @param {string} [options.loop] Code to execute in the object loop. - * @param {string} [options.bottom] Code to execute after the iteration branches. - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - // data properties - iteratorData.shadowedProps = shadowedProps; - - // iterator options - iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; - iteratorData.init = 'iterable'; - iteratorData.useHas = true; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - iteratorData[key] = object[key]; - } - } - var args = iteratorData.args; - iteratorData.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + - 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + - 'objectTypes, nonEnumProps, stringClass, stringProto, toString', - 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' - ); - - // return the compiled function - return factory( - baseCreateCallback, errorClass, errorProto, hasOwnProperty, - indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, - objectTypes, nonEnumProps, stringClass, stringProto, toString - ); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || - (!support.argsClass && isArguments(value)) || - (!support.nodeClass && isNode(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (support.ownLast) { - forIn(value, function(value, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (!support.argsClass) { - isArguments = function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; - }; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = createIterator({ - 'args': 'object', - 'init': '[]', - 'top': 'if (!(objectTypes[typeof object])) return result', - 'loop': 'result.push(index)' - }); - - /** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", - 'array': "typeof length == 'number'", - 'keys': keys, - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'keys': keys, - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'array': false - }; - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the callback for each - * element in the collection. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createIterator(eachIteratorOptions); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; - } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } - * }; - * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' - * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' - */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } - * }; - * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' - * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' - */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' - */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); - - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; - } - } - return object; - } - - /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } - } - return object; - } - - /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value && value.nodeType === 1 || false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - (support.argsClass ? className == argsClass : isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value == 'function' && toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; - } - - /** - * Checks if `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * _.isPlainObject(new Shape); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/fred/); - * // => true - */ - function isRegExp(value) { - return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('fred'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } - */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } - * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } - */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } - } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? baseEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); - } - return accumulator; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.contains('pebbles', 'eb'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - baseEach(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - - /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } - * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } - */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - } - - /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 - */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - baseEach(collection, callback, thisArg); - } - return collection; - } - - /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' - */ - function forEachRight(collection, callback, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (support.unindexedChars && isString(collection)) { - iterable = collection.split(''); - } - baseEach(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(iterable[key], key, collection); - }); - } - return collection; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = lodash.createCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; - * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the collection. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] - */ - var pluck = map; - - /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Retrieves a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } else if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] - * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); - } - releaseObject(object); - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (support.unindexedChars && isString(collection)) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] - * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; - * }); - * // => 2 - * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 - */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 - * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 - */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] - */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] - */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; - } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] - */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; - - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); - } - } - releaseArray(caches); - releaseArray(seen); - return result; - } - - /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. - * - * @static - * @memberOf _ - * @category Arrays - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); - * - * console.log(array); - * // => [1, 3, 5] - * - * console.log(evens); - * // => [2, 4, 6] - */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); - } - - /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); - } - - /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. - * - * @static - * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed - */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' - * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; - * - * func(); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } - - /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; - * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; - * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' - */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. - * @example - * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 - * - * curried(1, 2)(3); - * // => 6 - * - * curried(1, 2, 3); - * // => 6 - */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); - * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); - * - * // ensure `batchLog` is executed once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * source.addEventListener('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * }, false); - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - wait = nativeMax(0, wait) || 0; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); - trailing = 'trailing' in options ? options.trailing : trailing; - } - var delayed = function() { - var remaining = wait - (now() - stamp); - if (remaining <= 0) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - }; - - var maxDelayed = function() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - }; - - return function() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - }; - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay execution. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it will be used to determine the cache key for storing the result - * based on the arguments provided to the memoized function. By default, the - * first argument provided to the memoized function is used as the cache key. - * The `func` is executed with the `this` binding of the memoized function. - * The result cache is exposed as the `cache` property on the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - * - * fibonacci(9) - * // => 34 - * - * var data = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // modifying the result cache - * var get = _.memoize(function(name) { return data[name]; }, _.identity); - * get('pebbles'); - * // => { 'name': 'pebbles', 'age': 1 } - * - * get.cache.pebbles.name = 'penelope'; - * get('pebbles'); - * // => { 'name': 'penelope', 'age': 1 } - */ - function memoize(func, resolver) { - if (!isFunction(func)) { - throw new TypeError; - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; - - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - } - memoized.cache = {}; - return memoized; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those provided to the new function. This - * method is similar to `_.bind` except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('fred'); - * // => 'hi fred' - */ - function partial(func) { - return createWrapper(func, 16, slice(arguments, 1)); - } - - /** - * This method is like `_.partial` except that `partial` arguments are - * appended to those provided to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createWrapper(func, 32, null, slice(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` function - * at most once per every `wait` milliseconds. Provide an options object to - * indicate that `func` should be invoked on the leading and/or trailing edge - * of the `wait` timeout. Subsequent calls to the throttled function will - * return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle executions to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - * - * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? options.leading : leading; - trailing = 'trailing' in options ? options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = wait; - debounceOptions.trailing = trailing; - - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Additional arguments provided to the function are appended - * to those provided to the wrapper function. The wrapper is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

                  ' + func(text) + '

                  '; - * }); - * - * p('Fred, Wilma, & Pebbles'); - * // => '

                  Fred, Wilma, & Pebbles

                  ' - */ - function wrap(value, wrapper) { - return createWrapper(wrapper, 16, [value]); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. - * @example - * - * var object = { 'name': 'fred' }; - * var getter = _.constant(object); - * getter() === object; - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ - function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; - - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } - } - return result; - }; - } - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} string The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('Fred, Wilma, & Pebbles'); - * // => 'Fred, Wilma, & Pebbles' - */ - function escape(string) { - return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds function properties of a source object to the destination object. - * If `object` is a function methods will be added to its prototype as well. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Function|Object} [object=lodash] object The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options] The options object. - * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. - * @example - * - * function capitalize(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * - * _.mixin({ 'capitalize': capitalize }); - * _.capitalize('fred'); - * // => 'Fred' - * - * _('fred').capitalize().value(); - * // => 'Fred' - * - * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); - * _('fred').capitalize(); - * // => 'Fred' - */ - function mixin(object, source, options) { - var chain = true, - methodNames = source && functions(source); - - if (!source || (!options && !methodNames.length)) { - if (options == null) { - options = source; - } - ctor = lodashWrapper; - source = object; - object = lodash; - methodNames = functions(source); - } - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - var ctor = object, - isFunc = isFunction(ctor); - - forEach(methodNames, function(methodName) { - var func = object[methodName] = source[methodName]; - if (isFunc) { - ctor.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new ctor(result); - result.__chain__ = chainAll; - } - return result; - }; - } - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - context._ = oldDash; - return this; - } - - /** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ - function noop() { - // no operation performed - } - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var stamp = _.now(); - * _.defer(function() { console.log(_.now() - stamp); }); - * // => logs the number of milliseconds it took for the deferred function to be called - */ - var now = isNative(now = Date.now) && now || function() { - return new Date().getTime(); - }; - - /** - * Converts the given value into an integer of the specified radix. - * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the - * `value` is a hexadecimal, in which case a `radix` of `16` is used. - * - * Note: This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See http://es5.github.io/#E. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} value The value to parse. - * @param {number} [radix] The radix used to interpret the value to parse. - * @returns {number} Returns the new integer value. - * @example - * - * _.parseInt('08'); - * // => 8 - */ - var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` - return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); - }; - - /** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example - * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; - * - * var getName = _.property('name'); - * - * _.map(characters, getName); - * // => ['barney', 'fred'] - * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] - */ - function property(key) { - return function(object) { - return object[key]; - }; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number will be - * returned. If `floating` is truey or either `min` or `max` are floats a - * floating-point number will be returned instead of an integer. - * - * @static - * @memberOf _ - * @category Utilities - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating=false] Specify returning a floating-point number. - * @returns {number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (typeof min == 'boolean' && noMax) { - floating = min; - min = 1; - } - else if (!noMax && typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); - } - return baseRandom(min, max); - } - - /** - * Resolves the value of property `key` on `object`. If `key` is a function - * it will be invoked with the `this` binding of `object` and its result returned, - * else the property value is returned. If `object` is falsey then `undefined` - * is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to resolve. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, key) { - if (object) { - var value = object[key]; - return isFunction(value) ? object[key]() : value; - } - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * For more information on precompiling templates see: - * http://lodash.com/custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} text The template text. - * @param {Object} data The data object used to populate the text. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as local variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [sourceURL] The sourceURL of the template's compiled source. - * @param {string} [variable] The data object variable name. - * @returns {Function|string} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': ' - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.css b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7cd..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.js deleted file mode 100644 index ef51e038..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/prettify.js +++ /dev/null @@ -1 +0,0 @@ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.html deleted file mode 100644 index ef3bcc4f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.html +++ /dev/null @@ -1,350 +0,0 @@ - - - - Code coverage report for vinyl/ - - - - - - - -
                  -

                  Code coverage report for vinyl/

                  -

                  - - Statements: 100% (89 / 89)      - - - Branches: 100% (76 / 76)      - - - Functions: 100% (15 / 15)      - - - Lines: 100% (82 / 82)      - - Ignored: none      -

                  -
                  All files » vinyl/
                  -
                  -
                  -
                  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  FileStatementsBranchesFunctionsLines
                  index.js100%(89 / 89)100%(76 / 76)100%(15 / 15)100%(82 / 82)
                  -
                  -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html deleted file mode 100644 index 36a4d769..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html +++ /dev/null @@ -1,847 +0,0 @@ - - - - Code coverage report for vinyl/index.js - - - - - - - -
                  -

                  Code coverage report for vinyl/index.js

                  -

                  - - Statements: 100% (89 / 89)      - - - Branches: 100% (76 / 76)      - - - Functions: 100% (15 / 15)      - - - Lines: 100% (82 / 82)      - - Ignored: none      -

                  -
                  All files » vinyl/ » index.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -1761 -1 -1 -1 -1 -1 -1 -1 -1 -  -1 -73 -  -  -73 -73 -  -  -73 -73 -  -  -  -73 -  -  -73 -  -  -1 -26 -  -  -1 -29 -  -  -1 -6 -  -  -  -1 -3 -  -  -1 -14 -2 -  -  -  -12 -7 -  -  -  -  -5 -5 -  -  -  -14 -14 -1 -1 -13 -6 -  -  -14 -  -  -  -  -  -  -  -  -14 -  -75 -  -  -70 -  -5 -  -14 -  -  -1 -6 -6 -  -6 -2 -  -4 -2 -1 -  -1 -  -2 -  -  -  -2 -2 -  -  -1 -6 -  -  -6 -  -6 -4 -  -  -6 -3 -  -  -6 -1 -  -  -6 -  -  -  -  -1 -  -99 -  -  -78 -1 -  -77 -  -  -  -  -1 -  -7 -6 -5 -  -  -1 -  -  -  -1 -  -46 -  -  -9 -  -  -8 -5 -  -  -  -  -1 - 
                  var path = require('path');
                  -var clone = require('lodash').clone;
                  -var cloneStats = require('clone-stats');
                  -var cloneBuffer = require('./lib/cloneBuffer');
                  -var isBuffer = require('./lib/isBuffer');
                  -var isStream = require('./lib/isStream');
                  -var isNull = require('./lib/isNull');
                  -var inspectStream = require('./lib/inspectStream');
                  -var Stream = require('stream');
                  - 
                  -function File(file) {
                  -  if (!file) file = {};
                  - 
                  -  // record path change
                  -  var history = file.path ? [file.path] : file.history;
                  -  this.history = history || [];
                  - 
                  -  // TODO: should this be moved to vinyl-fs?
                  -  this.cwd = file.cwd || process.cwd();
                  -  this.base = file.base || this.cwd;
                  - 
                  -  // stat = fs stats object
                  -  // TODO: should this be moved to vinyl-fs?
                  -  this.stat = file.stat || null;
                  - 
                  -  // contents = stream, buffer, or null if not read
                  -  this.contents = file.contents || null;
                  -}
                  - 
                  -File.prototype.isBuffer = function() {
                  -  return isBuffer(this.contents);
                  -};
                  - 
                  -File.prototype.isStream = function() {
                  -  return isStream(this.contents);
                  -};
                  - 
                  -File.prototype.isNull = function() {
                  -  return isNull(this.contents);
                  -};
                  - 
                  -// TODO: should this be moved to vinyl-fs?
                  -File.prototype.isDirectory = function() {
                  -  return this.isNull() && this.stat && this.stat.isDirectory();
                  -};
                  - 
                  -File.prototype.clone = function(opt) {
                  -  if (typeof opt === 'boolean') {
                  -    opt = {
                  -      deep: opt,
                  -      contents: true
                  -    };
                  -  } else if (!opt) {
                  -    opt = {
                  -      deep: false,
                  -      contents: true
                  -    };
                  -  } else {
                  -    opt.deep = opt.deep === true;
                  -    opt.contents = opt.contents !== false;
                  -  }
                  - 
                  -  // clone our file contents
                  -  var contents;
                  -  if (this.isStream()) {
                  -    contents = this.contents.pipe(new Stream.PassThrough());
                  -    this.contents = this.contents.pipe(new Stream.PassThrough());
                  -  } else if (this.isBuffer()) {
                  -    contents = opt.contents ? cloneBuffer(this.contents) : this.contents;
                  -  }
                  - 
                  -  var file = new File({
                  -    cwd: this.cwd,
                  -    base: this.base,
                  -    stat: (this.stat ? cloneStats(this.stat) : null),
                  -    history: this.history.slice(),
                  -    contents: contents
                  -  });
                  - 
                  -  // clone our custom properties
                  -  Object.keys(this).forEach(function(key) {
                  -    // ignore built-in fields
                  -    if (key === '_contents' || key === 'stat' ||
                  -      key === 'history' || key === 'path' ||
                  -      key === 'base' || key === 'cwd') {
                  -      return;
                  -    }
                  -    file[key] = opt.deep ? clone(this[key], true) : this[key];
                  -  }, this);
                  -  return file;
                  -};
                  - 
                  -File.prototype.pipe = function(stream, opt) {
                  -  if (!opt) opt = {};
                  -  if (typeof opt.end === 'undefined') opt.end = true;
                  - 
                  -  if (this.isStream()) {
                  -    return this.contents.pipe(stream, opt);
                  -  }
                  -  if (this.isBuffer()) {
                  -    if (opt.end) {
                  -      stream.end(this.contents);
                  -    } else {
                  -      stream.write(this.contents);
                  -    }
                  -    return stream;
                  -  }
                  - 
                  -  // isNull
                  -  if (opt.end) stream.end();
                  -  return stream;
                  -};
                  - 
                  -File.prototype.inspect = function() {
                  -  var inspect = [];
                  - 
                  -  // use relative path if possible
                  -  var filePath = (this.base && this.path) ? this.relative : this.path;
                  - 
                  -  if (filePath) {
                  -    inspect.push('"'+filePath+'"');
                  -  }
                  - 
                  -  if (this.isBuffer()) {
                  -    inspect.push(this.contents.inspect());
                  -  }
                  - 
                  -  if (this.isStream()) {
                  -    inspect.push(inspectStream(this.contents));
                  -  }
                  - 
                  -  return '<File '+inspect.join(' ')+'>';
                  -};
                  - 
                  -// virtual attributes
                  -// or stuff with extra logic
                  -Object.defineProperty(File.prototype, 'contents', {
                  -  get: function() {
                  -    return this._contents;
                  -  },
                  -  set: function(val) {
                  -    if (!isBuffer(val) && !isStream(val) && !isNull(val)) {
                  -      throw new Error('File.contents can only be a Buffer, a Stream, or null.');
                  -    }
                  -    this._contents = val;
                  -  }
                  -});
                  - 
                  -// TODO: should this be moved to vinyl-fs?
                  -Object.defineProperty(File.prototype, 'relative', {
                  -  get: function() {
                  -    if (!this.base) throw new Error('No base specified! Can not get relative.');
                  -    if (!this.path) throw new Error('No path specified! Can not get relative.');
                  -    return path.relative(this.base, this.path);
                  -  },
                  -  set: function() {
                  -    throw new Error('File.relative is generated from the base and path attributes. Do not modify it.');
                  -  }
                  -});
                  - 
                  -Object.defineProperty(File.prototype, 'path', {
                  -  get: function() {
                  -    return this.history[this.history.length - 1];
                  -  },
                  -  set: function(path) {
                  -    if (typeof path !== 'string') throw new Error('path should be string');
                  - 
                  -    // record history only when path changed
                  -    if (path && path !== this.path) {
                  -      this.history.push(path);
                  -    }
                  -  }
                  -});
                  - 
                  -module.exports = File;
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html deleted file mode 100644 index 39ec92bc..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - Code coverage report for vinyl/lib/cloneBuffer.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/cloneBuffer.js

                  -

                  - - Statements: 100% (5 / 5)      - - - Branches: 100% (0 / 0)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (5 / 5)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » cloneBuffer.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -7 -81 -  -1 -7 -7 -7 -  - 
                  var Buffer = require('buffer').Buffer;
                  - 
                  -module.exports = function(buf) {
                  -  var out = new Buffer(buf.length);
                  -  buf.copy(out);
                  -  return out;
                  -};
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html deleted file mode 100644 index 5288f5aa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - Code coverage report for vinyl/lib/ - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/

                  -

                  - - Statements: 100% (22 / 22)      - - - Branches: 100% (8 / 8)      - - - Functions: 100% (5 / 5)      - - - Lines: 100% (20 / 20)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/
                  -
                  -
                  -
                  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  FileStatementsBranchesFunctionsLines
                  cloneBuffer.js100%(5 / 5)100%(0 / 0)100%(1 / 1)100%(5 / 5)
                  inspectStream.js100%(8 / 8)100%(4 / 4)100%(1 / 1)100%(6 / 6)
                  isBuffer.js100%(4 / 4)100%(2 / 2)100%(1 / 1)100%(4 / 4)
                  isNull.js100%(2 / 2)100%(0 / 0)100%(1 / 1)100%(2 / 2)
                  isStream.js100%(3 / 3)100%(2 / 2)100%(1 / 1)100%(3 / 3)
                  -
                  -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html deleted file mode 100644 index e8e5b360..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - Code coverage report for vinyl/lib/inspectStream.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/inspectStream.js

                  -

                  - - Statements: 100% (8 / 8)      - - - Branches: 100% (4 / 4)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (6 / 6)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » inspectStream.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -121 -  -1 -9 -  -7 -  -7 -  -7 -  - 
                  var isStream = require('./isStream');
                  - 
                  -module.exports = function(stream) {
                  -  if (!isStream(stream)) return;
                  - 
                  -  var streamType = stream.constructor.name;
                  -  // avoid StreamStream
                  -  if (streamType === 'Stream') streamType = '';
                  - 
                  -  return '<'+streamType+'Stream>';
                  -};
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html deleted file mode 100644 index a44efe47..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html +++ /dev/null @@ -1,340 +0,0 @@ - - - - Code coverage report for vinyl/lib/isBuffer.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/isBuffer.js

                  -

                  - - Statements: 100% (4 / 4)      - - - Branches: 100% (2 / 2)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (4 / 4)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » isBuffer.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -71 -1 -  -  -1 -108 - 
                  var buf = require('buffer');
                  -var Buffer = buf.Buffer;
                  - 
                  -// could use Buffer.isBuffer but this is the same exact thing...
                  -module.exports = function(o) {
                  -  return typeof o === 'object' && o instanceof Buffer;
                  -};
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html deleted file mode 100644 index 010d3e00..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - Code coverage report for vinyl/lib/isNull.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/isNull.js

                  -

                  - - Statements: 100% (2 / 2)      - - - Branches: 100% (0 / 0)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (2 / 2)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » isNull.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -41 -57 -  - 
                  module.exports = function(v) {
                  -  return v === null;
                  -};
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html deleted file mode 100644 index 511186fe..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - Code coverage report for vinyl/lib/isStream.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/isStream.js

                  -

                  - - Statements: 100% (3 / 3)      - - - Branches: 100% (2 / 2)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (3 / 3)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » isStream.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -51 -  -1 -99 - 
                  var Stream = require('stream').Stream;
                  - 
                  -module.exports = function(o) {
                  -  return !!o && o instanceof Stream;
                  -};
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov.info b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov.info deleted file mode 100644 index bbebe386..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/coverage/lcov.info +++ /dev/null @@ -1,280 +0,0 @@ -TN: -SF:/Users/contra/Projects/vinyl/index.js -FN:11,File -FN:30,(anonymous_2) -FN:34,(anonymous_3) -FN:38,(anonymous_4) -FN:43,(anonymous_5) -FN:47,(anonymous_6) -FN:81,(anonymous_7) -FN:93,(anonymous_8) -FN:114,(anonymous_9) -FN:138,(anonymous_10) -FN:141,(anonymous_11) -FN:151,(anonymous_12) -FN:156,(anonymous_13) -FN:162,(anonymous_14) -FN:165,(anonymous_15) -FNF:15 -FNH:15 -FNDA:73,File -FNDA:26,(anonymous_2) -FNDA:29,(anonymous_3) -FNDA:6,(anonymous_4) -FNDA:3,(anonymous_5) -FNDA:14,(anonymous_6) -FNDA:75,(anonymous_7) -FNDA:6,(anonymous_8) -FNDA:6,(anonymous_9) -FNDA:99,(anonymous_10) -FNDA:78,(anonymous_11) -FNDA:7,(anonymous_12) -FNDA:1,(anonymous_13) -FNDA:46,(anonymous_14) -FNDA:9,(anonymous_15) -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:11,1 -DA:12,73 -DA:15,73 -DA:16,73 -DA:19,73 -DA:20,73 -DA:24,73 -DA:27,73 -DA:30,1 -DA:31,26 -DA:34,1 -DA:35,29 -DA:38,1 -DA:39,6 -DA:43,1 -DA:44,3 -DA:47,1 -DA:48,14 -DA:49,2 -DA:53,12 -DA:54,7 -DA:59,5 -DA:60,5 -DA:64,14 -DA:65,14 -DA:66,1 -DA:67,1 -DA:68,13 -DA:69,6 -DA:72,14 -DA:81,14 -DA:83,75 -DA:86,70 -DA:88,5 -DA:90,14 -DA:93,1 -DA:94,6 -DA:95,6 -DA:97,6 -DA:98,2 -DA:100,4 -DA:101,2 -DA:102,1 -DA:104,1 -DA:106,2 -DA:110,2 -DA:111,2 -DA:114,1 -DA:115,6 -DA:118,6 -DA:120,6 -DA:121,4 -DA:124,6 -DA:125,3 -DA:128,6 -DA:129,1 -DA:132,6 -DA:137,1 -DA:139,99 -DA:142,78 -DA:143,1 -DA:145,77 -DA:150,1 -DA:152,7 -DA:153,6 -DA:154,5 -DA:157,1 -DA:161,1 -DA:163,46 -DA:166,9 -DA:169,8 -DA:170,5 -DA:175,1 -LF:82 -LH:82 -BRDA:12,1,0,14 -BRDA:12,1,1,59 -BRDA:15,2,0,25 -BRDA:15,2,1,48 -BRDA:16,3,0,73 -BRDA:16,3,1,33 -BRDA:19,4,0,73 -BRDA:19,4,1,32 -BRDA:20,5,0,73 -BRDA:20,5,1,39 -BRDA:24,6,0,73 -BRDA:24,6,1,65 -BRDA:27,7,0,73 -BRDA:27,7,1,44 -BRDA:44,8,0,3 -BRDA:44,8,1,1 -BRDA:44,8,2,1 -BRDA:48,9,0,2 -BRDA:48,9,1,12 -BRDA:53,10,0,7 -BRDA:53,10,1,5 -BRDA:65,11,0,1 -BRDA:65,11,1,13 -BRDA:68,12,0,6 -BRDA:68,12,1,7 -BRDA:69,13,0,5 -BRDA:69,13,1,1 -BRDA:75,14,0,2 -BRDA:75,14,1,12 -BRDA:83,15,0,70 -BRDA:83,15,1,5 -BRDA:83,16,0,75 -BRDA:83,16,1,61 -BRDA:83,16,2,47 -BRDA:83,16,3,33 -BRDA:83,16,4,33 -BRDA:83,16,5,19 -BRDA:88,17,0,2 -BRDA:88,17,1,3 -BRDA:94,18,0,3 -BRDA:94,18,1,3 -BRDA:95,19,0,3 -BRDA:95,19,1,3 -BRDA:97,20,0,2 -BRDA:97,20,1,4 -BRDA:100,21,0,2 -BRDA:100,21,1,2 -BRDA:101,22,0,1 -BRDA:101,22,1,1 -BRDA:110,23,0,1 -BRDA:110,23,1,1 -BRDA:118,24,0,3 -BRDA:118,24,1,3 -BRDA:118,25,0,6 -BRDA:118,25,1,5 -BRDA:120,26,0,4 -BRDA:120,26,1,2 -BRDA:124,27,0,3 -BRDA:124,27,1,3 -BRDA:128,28,0,1 -BRDA:128,28,1,5 -BRDA:142,29,0,1 -BRDA:142,29,1,77 -BRDA:142,30,0,78 -BRDA:142,30,1,57 -BRDA:142,30,2,46 -BRDA:152,31,0,1 -BRDA:152,31,1,6 -BRDA:153,32,0,1 -BRDA:153,32,1,5 -BRDA:166,33,0,1 -BRDA:166,33,1,8 -BRDA:169,34,0,5 -BRDA:169,34,1,3 -BRDA:169,35,0,8 -BRDA:169,35,1,7 -BRF:76 -BRH:76 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/cloneBuffer.js -FN:3,(anonymous_1) -FNF:1 -FNH:1 -FNDA:7,(anonymous_1) -DA:1,1 -DA:3,1 -DA:4,7 -DA:5,7 -DA:6,7 -LF:5 -LH:5 -BRF:0 -BRH:0 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/isBuffer.js -FN:5,(anonymous_1) -FNF:1 -FNH:1 -FNDA:108,(anonymous_1) -DA:1,1 -DA:2,1 -DA:5,1 -DA:6,108 -LF:4 -LH:4 -BRDA:6,1,0,108 -BRDA:6,1,1,107 -BRF:2 -BRH:2 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/isStream.js -FN:3,(anonymous_1) -FNF:1 -FNH:1 -FNDA:99,(anonymous_1) -DA:1,1 -DA:3,1 -DA:4,99 -LF:3 -LH:3 -BRDA:4,1,0,99 -BRDA:4,1,1,40 -BRF:2 -BRH:2 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/isNull.js -FN:1,(anonymous_1) -FNF:1 -FNH:1 -FNDA:57,(anonymous_1) -DA:1,1 -DA:2,57 -LF:2 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/inspectStream.js -FN:3,(anonymous_1) -FNF:1 -FNH:1 -FNDA:9,(anonymous_1) -DA:1,1 -DA:3,1 -DA:4,9 -DA:6,7 -DA:8,7 -DA:10,7 -LF:6 -LH:6 -BRDA:4,1,0,2 -BRDA:4,1,1,7 -BRDA:8,2,0,1 -BRDA:8,2,1,6 -BRF:4 -BRH:4 -end_of_record diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/index.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/index.js deleted file mode 100644 index 09913c3a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/index.js +++ /dev/null @@ -1,175 +0,0 @@ -var path = require('path'); -var clone = require('lodash').clone; -var cloneStats = require('clone-stats'); -var cloneBuffer = require('./lib/cloneBuffer'); -var isBuffer = require('./lib/isBuffer'); -var isStream = require('./lib/isStream'); -var isNull = require('./lib/isNull'); -var inspectStream = require('./lib/inspectStream'); -var Stream = require('stream'); - -function File(file) { - if (!file) file = {}; - - // record path change - var history = file.path ? [file.path] : file.history; - this.history = history || []; - - // TODO: should this be moved to vinyl-fs? - this.cwd = file.cwd || process.cwd(); - this.base = file.base || this.cwd; - - // stat = fs stats object - // TODO: should this be moved to vinyl-fs? - this.stat = file.stat || null; - - // contents = stream, buffer, or null if not read - this.contents = file.contents || null; -} - -File.prototype.isBuffer = function() { - return isBuffer(this.contents); -}; - -File.prototype.isStream = function() { - return isStream(this.contents); -}; - -File.prototype.isNull = function() { - return isNull(this.contents); -}; - -// TODO: should this be moved to vinyl-fs? -File.prototype.isDirectory = function() { - return this.isNull() && this.stat && this.stat.isDirectory(); -}; - -File.prototype.clone = function(opt) { - if (typeof opt === 'boolean') { - opt = { - deep: opt, - contents: true - }; - } else if (!opt) { - opt = { - deep: false, - contents: true - }; - } else { - opt.deep = opt.deep === true; - opt.contents = opt.contents !== false; - } - - // clone our file contents - var contents; - if (this.isStream()) { - contents = this.contents.pipe(new Stream.PassThrough()); - this.contents = this.contents.pipe(new Stream.PassThrough()); - } else if (this.isBuffer()) { - contents = opt.contents ? cloneBuffer(this.contents) : this.contents; - } - - var file = new File({ - cwd: this.cwd, - base: this.base, - stat: (this.stat ? cloneStats(this.stat) : null), - history: this.history.slice(), - contents: contents - }); - - // clone our custom properties - Object.keys(this).forEach(function(key) { - // ignore built-in fields - if (key === '_contents' || key === 'stat' || - key === 'history' || key === 'path' || - key === 'base' || key === 'cwd') { - return; - } - file[key] = opt.deep ? clone(this[key], true) : this[key]; - }, this); - return file; -}; - -File.prototype.pipe = function(stream, opt) { - if (!opt) opt = {}; - if (typeof opt.end === 'undefined') opt.end = true; - - if (this.isStream()) { - return this.contents.pipe(stream, opt); - } - if (this.isBuffer()) { - if (opt.end) { - stream.end(this.contents); - } else { - stream.write(this.contents); - } - return stream; - } - - // isNull - if (opt.end) stream.end(); - return stream; -}; - -File.prototype.inspect = function() { - var inspect = []; - - // use relative path if possible - var filePath = (this.base && this.path) ? this.relative : this.path; - - if (filePath) { - inspect.push('"'+filePath+'"'); - } - - if (this.isBuffer()) { - inspect.push(this.contents.inspect()); - } - - if (this.isStream()) { - inspect.push(inspectStream(this.contents)); - } - - return ''; -}; - -// virtual attributes -// or stuff with extra logic -Object.defineProperty(File.prototype, 'contents', { - get: function() { - return this._contents; - }, - set: function(val) { - if (!isBuffer(val) && !isStream(val) && !isNull(val)) { - throw new Error('File.contents can only be a Buffer, a Stream, or null.'); - } - this._contents = val; - } -}); - -// TODO: should this be moved to vinyl-fs? -Object.defineProperty(File.prototype, 'relative', { - get: function() { - if (!this.base) throw new Error('No base specified! Can not get relative.'); - if (!this.path) throw new Error('No path specified! Can not get relative.'); - return path.relative(this.base, this.path); - }, - set: function() { - throw new Error('File.relative is generated from the base and path attributes. Do not modify it.'); - } -}); - -Object.defineProperty(File.prototype, 'path', { - get: function() { - return this.history[this.history.length - 1]; - }, - set: function(path) { - if (typeof path !== 'string') throw new Error('path should be string'); - - // record history only when path changed - if (path && path !== this.path) { - this.history.push(path); - } - } -}); - -module.exports = File; diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/cloneBuffer.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/cloneBuffer.js deleted file mode 100644 index 89f09eda..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/cloneBuffer.js +++ /dev/null @@ -1,7 +0,0 @@ -var Buffer = require('buffer').Buffer; - -module.exports = function(buf) { - var out = new Buffer(buf.length); - buf.copy(out); - return out; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/inspectStream.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/inspectStream.js deleted file mode 100644 index d36df6ff..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/inspectStream.js +++ /dev/null @@ -1,11 +0,0 @@ -var isStream = require('./isStream'); - -module.exports = function(stream) { - if (!isStream(stream)) return; - - var streamType = stream.constructor.name; - // avoid StreamStream - if (streamType === 'Stream') streamType = ''; - - return '<'+streamType+'Stream>'; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isBuffer.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isBuffer.js deleted file mode 100644 index 0e23782c..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isBuffer.js +++ /dev/null @@ -1,7 +0,0 @@ -var buf = require('buffer'); -var Buffer = buf.Buffer; - -// could use Buffer.isBuffer but this is the same exact thing... -module.exports = function(o) { - return typeof o === 'object' && o instanceof Buffer; -}; \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isNull.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isNull.js deleted file mode 100644 index 7f22c63a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isNull.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function(v) { - return v === null; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isStream.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isStream.js deleted file mode 100644 index 9ce0929b..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/lib/isStream.js +++ /dev/null @@ -1,5 +0,0 @@ -var Stream = require('stream').Stream; - -module.exports = function(o) { - return !!o && o instanceof Stream; -}; \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/LICENSE.md b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/LICENSE.md deleted file mode 100644 index 146cb32a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -## The MIT License (MIT) ## - -Copyright (c) 2014 Hugh Kennedy - -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/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/README.md b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/README.md deleted file mode 100644 index 8b12b6fa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# clone-stats [![Flattr this!](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=hughskennedy&url=http://github.com/hughsk/clone-stats&title=clone-stats&description=hughsk/clone-stats%20on%20GitHub&language=en_GB&tags=flattr,github,javascript&category=software)[![experimental](http://hughsk.github.io/stability-badges/dist/experimental.svg)](http://github.com/hughsk/stability-badges) # - -Safely clone node's -[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) instances without -losing their class methods, i.e. `stat.isDirectory()` and co. - -## Usage ## - -[![clone-stats](https://nodei.co/npm/clone-stats.png?mini=true)](https://nodei.co/npm/clone-stats) - -### `copy = require('clone-stats')(stat)` ### - -Returns a clone of the original `fs.Stats` instance (`stat`). - -## License ## - -MIT. See [LICENSE.md](http://github.com/hughsk/clone-stats/blob/master/LICENSE.md) for details. diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/index.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/index.js deleted file mode 100644 index e797cfe6..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/index.js +++ /dev/null @@ -1,13 +0,0 @@ -var Stat = require('fs').Stats - -module.exports = cloneStats - -function cloneStats(stats) { - var replacement = new Stat - - Object.keys(stats).forEach(function(key) { - replacement[key] = stats[key] - }) - - return replacement -} diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/package.json b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/package.json deleted file mode 100644 index e6911657..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "clone-stats", - "description": "Safely clone node's fs.Stats instances without losing their class methods", - "version": "0.0.1", - "main": "index.js", - "browser": "index.js", - "dependencies": {}, - "devDependencies": { - "tape": "~2.3.2" - }, - "scripts": { - "test": "node test" - }, - "author": { - "name": "Hugh Kennedy", - "email": "hughskennedy@gmail.com", - "url": "http://hughsk.io/" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "git://github.com/hughsk/clone-stats" - }, - "bugs": { - "url": "https://github.com/hughsk/clone-stats/issues" - }, - "homepage": "https://github.com/hughsk/clone-stats", - "keywords": [ - "stats", - "fs", - "clone", - "copy", - "prototype" - ], - "readme": "# clone-stats [![Flattr this!](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=hughskennedy&url=http://github.com/hughsk/clone-stats&title=clone-stats&description=hughsk/clone-stats%20on%20GitHub&language=en_GB&tags=flattr,github,javascript&category=software)[![experimental](http://hughsk.github.io/stability-badges/dist/experimental.svg)](http://github.com/hughsk/stability-badges) #\n\nSafely clone node's\n[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) instances without\nlosing their class methods, i.e. `stat.isDirectory()` and co.\n\n## Usage ##\n\n[![clone-stats](https://nodei.co/npm/clone-stats.png?mini=true)](https://nodei.co/npm/clone-stats)\n\n### `copy = require('clone-stats')(stat)` ###\n\nReturns a clone of the original `fs.Stats` instance (`stat`).\n\n## License ##\n\nMIT. See [LICENSE.md](http://github.com/hughsk/clone-stats/blob/master/LICENSE.md) for details.\n", - "readmeFilename": "README.md", - "_id": "clone-stats@0.0.1", - "dist": { - "shasum": "b88f94a82cf38b8791d58046ea4029ad88ca99d1", - "tarball": "http://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" - }, - "_from": "clone-stats@^0.0.1", - "_npmVersion": "1.3.22", - "_npmUser": { - "name": "hughsk", - "email": "hughskennedy@gmail.com" - }, - "maintainers": [ - { - "name": "hughsk", - "email": "hughskennedy@gmail.com" - } - ], - "directories": {}, - "_shasum": "b88f94a82cf38b8791d58046ea4029ad88ca99d1", - "_resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/test.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/test.js deleted file mode 100644 index e4bb2814..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/node_modules/clone-stats/test.js +++ /dev/null @@ -1,36 +0,0 @@ -var test = require('tape') -var clone = require('./') -var fs = require('fs') - -test('file', function(t) { - compare(t, fs.statSync(__filename)) - t.end() -}) - -test('directory', function(t) { - compare(t, fs.statSync(__dirname)) - t.end() -}) - -function compare(t, stat) { - var copy = clone(stat) - - t.deepEqual(stat, copy, 'clone has equal properties') - t.ok(stat instanceof fs.Stats, 'original is an fs.Stat') - t.ok(copy instanceof fs.Stats, 'copy is an fs.Stat') - - ;['isDirectory' - , 'isFile' - , 'isBlockDevice' - , 'isCharacterDevice' - , 'isSymbolicLink' - , 'isFIFO' - , 'isSocket' - ].forEach(function(method) { - t.equal( - stat[method].call(stat) - , copy[method].call(copy) - , 'equal value for stat.' + method + '()' - ) - }) -} diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/package.json b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/package.json deleted file mode 100644 index 29020314..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "vinyl", - "description": "A virtual file format", - "version": "0.4.3", - "homepage": "http://github.com/wearefractal/vinyl", - "repository": { - "type": "git", - "url": "git://github.com/wearefractal/vinyl.git" - }, - "author": { - "name": "Fractal", - "email": "contact@wearefractal.com", - "url": "http://wearefractal.com/" - }, - "main": "./index.js", - "dependencies": { - "clone-stats": "^0.0.1", - "lodash": "^2.4.1" - }, - "devDependencies": { - "mocha": "^1.17.0", - "should": "^4.0.4", - "mocha-lcov-reporter": "^0.0.1", - "coveralls": "^2.6.1", - "istanbul": "^0.3.0", - "rimraf": "^2.2.5", - "jshint": "^2.4.1", - "buffer-equal": "0.0.1", - "lodash.templatesettings": "^2.4.1", - "event-stream": "^3.1.0" - }, - "scripts": { - "test": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter spec && jshint .", - "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" - }, - "engines": { - "node": ">= 0.9" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/wearefractal/vinyl/raw/master/LICENSE" - } - ], - "gitHead": "6eae432519b007c313a8df83b093adfb97a2944c", - "bugs": { - "url": "https://github.com/wearefractal/vinyl/issues" - }, - "_id": "vinyl@0.4.3", - "_shasum": "19f61a1b28e72b4c50697889dbe91d7503943ecf", - "_from": "vinyl@^0.4.0", - "_npmVersion": "1.4.21", - "_npmUser": { - "name": "fractal", - "email": "contact@wearefractal.com" - }, - "maintainers": [ - { - "name": "fractal", - "email": "contact@wearefractal.com" - } - ], - "dist": { - "shasum": "19f61a1b28e72b4c50697889dbe91d7503943ecf", - "tarball": "http://registry.npmjs.org/vinyl/-/vinyl-0.4.3.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.3.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/perf/clone.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/perf/clone.js deleted file mode 100644 index 4df85787..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/perf/clone.js +++ /dev/null @@ -1,59 +0,0 @@ -var File = require('../'); - -var contents = new Buffer('blah blah blah'); - -var originalFile = new File({ - path: 'yo.coffee', - contents: contents -}); - -// simulate some history -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; - -originalFile.ast = { - a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { - - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } -}; - -for (var i = 0; i < 10000; i++) { - originalFile.clone(true).ast; -} \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/File.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/File.js deleted file mode 100644 index 419e7aac..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/File.js +++ /dev/null @@ -1,753 +0,0 @@ -var Stream = require('stream'); -var fs = require('fs'); -var path = require('path'); -var es = require('event-stream'); -var File = require('../'); - -var should = require('should'); -require('mocha'); - -describe('File', function() { - describe('constructor()', function() { - it('should default cwd to process.cwd', function(done) { - var file = new File(); - file.cwd.should.equal(process.cwd()); - done(); - }); - - it('should default base to cwd', function(done) { - var cwd = '/'; - var file = new File({cwd: cwd}); - file.base.should.equal(cwd); - done(); - }); - - it('should default base to cwd even when none is given', function(done) { - var file = new File(); - file.base.should.equal(process.cwd()); - done(); - }); - - it('should default path to null', function(done) { - var file = new File(); - should.not.exist(file.path); - done(); - }); - - it('should default history to []', function(done) { - var file = new File(); - file.history.should.eql([]); - done(); - }); - - it('should default stat to null', function(done) { - var file = new File(); - should.not.exist(file.stat); - done(); - }); - - it('should default contents to null', function(done) { - var file = new File(); - should.not.exist(file.contents); - done(); - }); - - it('should set base to given value', function(done) { - var val = '/'; - var file = new File({base: val}); - file.base.should.equal(val); - done(); - }); - - it('should set cwd to given value', function(done) { - var val = '/'; - var file = new File({cwd: val}); - file.cwd.should.equal(val); - done(); - }); - - it('should set path to given value', function(done) { - var val = '/test.coffee'; - var file = new File({path: val}); - file.path.should.equal(val); - file.history.should.eql([val]); - done(); - }); - - it('should set history to given value', function(done) { - var val = '/test.coffee'; - var file = new File({history: [val]}); - file.path.should.equal(val); - file.history.should.eql([val]); - done(); - }); - - it('should set stat to given value', function(done) { - var val = {}; - var file = new File({stat: val}); - file.stat.should.equal(val); - done(); - }); - - it('should set contents to given value', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.contents.should.equal(val); - done(); - }); - }); - - describe('isBuffer()', function() { - it('should return true when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.isBuffer().should.equal(true); - done(); - }); - - it('should return false when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val}); - file.isBuffer().should.equal(false); - done(); - }); - - it('should return false when the contents are a null', function(done) { - var file = new File({contents: null}); - file.isBuffer().should.equal(false); - done(); - }); - }); - - describe('isStream()', function() { - it('should return false when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.isStream().should.equal(false); - done(); - }); - - it('should return true when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val}); - file.isStream().should.equal(true); - done(); - }); - - it('should return false when the contents are a null', function(done) { - var file = new File({contents: null}); - file.isStream().should.equal(false); - done(); - }); - }); - - describe('isNull()', function() { - it('should return false when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.isNull().should.equal(false); - done(); - }); - - it('should return false when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val}); - file.isNull().should.equal(false); - done(); - }); - - it('should return true when the contents are a null', function(done) { - var file = new File({contents: null}); - file.isNull().should.equal(true); - done(); - }); - }); - - describe('isDirectory()', function() { - var fakeStat = { - isDirectory: function() { - return true; - } - }; - - it('should return false when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val, stat: fakeStat}); - file.isDirectory().should.equal(false); - done(); - }); - - it('should return false when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val, stat: fakeStat}); - file.isDirectory().should.equal(false); - done(); - }); - - it('should return true when the contents are a null', function(done) { - var file = new File({contents: null, stat: fakeStat}); - file.isDirectory().should.equal(true); - done(); - }); - }); - - describe('clone()', function() { - it('should copy all attributes over with Buffer', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Buffer('test') - }; - var file = new File(options); - var file2 = file.clone(); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - file2.contents.should.not.equal(file.contents, 'buffer ref should be different'); - file2.contents.toString('utf8').should.equal(file.contents.toString('utf8')); - done(); - }); - - it('should copy buffer\'s reference with option contents: false', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.js', - contents: new Buffer('test') - }; - - var file = new File(options); - - var copy1 = file.clone({ contents: false }); - copy1.contents.should.equal(file.contents); - - var copy2 = file.clone({}); - copy2.contents.should.not.equal(file.contents); - - var copy3 = file.clone({ contents: 'any string' }); - copy3.contents.should.not.equal(file.contents); - - done(); - }); - - it('should copy all attributes over with Stream', function(done) { - var contents = new Stream.PassThrough(); - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: contents - }; - var file = new File(options); - var file2 = file.clone(); - - contents.write(new Buffer('wa')); - - process.nextTick(function() { - contents.write(new Buffer('dup')); - contents.end(); - }); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - file2.contents.should.not.equal(file.contents, 'stream ref should not be the same'); - file.contents.pipe(es.wait(function(err, data) { - file2.contents.pipe(es.wait(function(err, data2) { - data2.should.not.equal(data, 'stream contents ref should not be the same'); - data2.should.eql(data, 'stream contents should be the same'); - })); - })); - done(); - }); - - it('should copy all attributes over with null', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - var file = new File(options); - var file2 = file.clone(); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - should.not.exist(file2.contents); - done(); - }); - - it('should properly clone the `stat` property', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.js', - contents: new Buffer('test'), - stat: fs.statSync(__filename) - }; - - var file = new File(options); - var copy = file.clone(); - - copy.stat.isFile().should.equal(true); - copy.stat.isDirectory().should.equal(false); - should(file.stat instanceof fs.Stats).equal(true); - should(copy.stat instanceof fs.Stats).equal(true); - - done(); - }); - - it('should properly clone the `history` property', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.js', - contents: new Buffer('test'), - stat: fs.statSync(__filename) - }; - - var file = new File(options); - var copy = file.clone(); - - copy.history[0].should.equal(options.path); - copy.path = 'lol'; - file.path.should.not.equal(copy.path); - done(); - }); - - it('should copy custom properties', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - - var file = new File(options); - file.custom = { a: 'custom property' }; - - var file2 = file.clone(); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - file2.custom.should.equal(file.custom); - file2.custom.a.should.equal(file.custom.a); - - done(); - }); - - it('should copy history', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - - var file = new File(options); - file.path = '/test/test.js'; - file.path = '/test/test-938di2s.js'; - var file2 = file.clone(); - - file2.history.should.eql([ - '/test/test.coffee', - '/test/test.js', - '/test/test-938di2s.js' - ]); - file2.history.should.not.equal([ - '/test/test.coffee', - '/test/test.js', - '/test/test-938di2s.js' - ]); - file2.path.should.eql('/test/test-938di2s.js'); - - done(); - }); - - it('should copy all attributes deeply', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - - var file = new File(options); - file.custom = { a: 'custom property' }; - - var file2 = file.clone(true); - file2.custom.should.eql(file.custom); - file2.custom.should.not.equal(file.custom); - file2.custom.a.should.equal(file.custom.a); - - var file3 = file.clone({ deep: true }); - file3.custom.should.eql(file.custom); - file3.custom.should.not.equal(file.custom); - file3.custom.a.should.equal(file.custom.a); - - var file4 = file.clone(false); - file4.custom.should.eql(file.custom); - file4.custom.should.equal(file.custom); - file4.custom.a.should.equal(file.custom.a); - - var file5 = file.clone({ deep: false }); - file5.custom.should.eql(file.custom); - file5.custom.should.equal(file.custom); - file5.custom.a.should.equal(file.custom.a); - - done(); - }); - }); - - describe('pipe()', function() { - it('should write to stream with Buffer', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Buffer('test') - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(options.contents.toString('utf8')); - }); - stream.on('end', function() { - done(); - }); - var ret = file.pipe(stream); - ret.should.equal(stream, 'should return the stream'); - }); - - it('should pipe to stream with Stream', function(done) { - var testChunk = new Buffer('test'); - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Stream.PassThrough() - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(testChunk.toString('utf8')); - done(); - }); - var ret = file.pipe(stream); - ret.should.equal(stream, 'should return the stream'); - - file.contents.write(testChunk); - }); - - it('should do nothing with null', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function() { - throw new Error('should not write'); - }); - stream.on('end', function() { - done(); - }); - var ret = file.pipe(stream); - ret.should.equal(stream, 'should return the stream'); - }); - - it('should write to stream with Buffer', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Buffer('test') - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(options.contents.toString('utf8')); - done(); - }); - stream.on('end', function() { - throw new Error('should not end'); - }); - var ret = file.pipe(stream, {end: false}); - ret.should.equal(stream, 'should return the stream'); - }); - - it('should pipe to stream with Stream', function(done) { - var testChunk = new Buffer('test'); - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Stream.PassThrough() - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(testChunk.toString('utf8')); - done(); - }); - stream.on('end', function() { - throw new Error('should not end'); - }); - var ret = file.pipe(stream, {end: false}); - ret.should.equal(stream, 'should return the stream'); - - file.contents.write(testChunk); - }); - - it('should do nothing with null', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function() { - throw new Error('should not write'); - }); - stream.on('end', function() { - throw new Error('should not end'); - }); - var ret = file.pipe(stream, {end: false}); - ret.should.equal(stream, 'should return the stream'); - process.nextTick(done); - }); - }); - - describe('inspect()', function() { - it('should return correct format when no contents and no path', function(done) { - var file = new File(); - file.inspect().should.equal(''); - done(); - }); - - it('should return correct format when Buffer and no path', function(done) { - var val = new Buffer('test'); - var file = new File({ - contents: val - }); - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when Buffer and relative path', function(done) { - var val = new Buffer('test'); - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: val - }); - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when Buffer and only path and no base', function(done) { - var val = new Buffer('test'); - var file = new File({ - cwd: '/', - path: '/test/test.coffee', - contents: val - }); - delete file.base; - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when Stream and relative path', function(done) { - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Stream.PassThrough() - }); - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when null and relative path', function(done) { - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }); - file.inspect().should.equal(''); - done(); - }); - }); - - describe('contents get/set', function() { - it('should work with Buffer', function(done) { - var val = new Buffer('test'); - var file = new File(); - file.contents = val; - file.contents.should.equal(val); - done(); - }); - - it('should work with Stream', function(done) { - var val = new Stream.PassThrough(); - var file = new File(); - file.contents = val; - file.contents.should.equal(val); - done(); - }); - - it('should work with null', function(done) { - var val = null; - var file = new File(); - file.contents = val; - (file.contents === null).should.equal(true); - done(); - }); - - it('should not work with string', function(done) { - var val = 'test'; - var file = new File(); - try { - file.contents = val; - } catch (err) { - should.exist(err); - done(); - } - }); - }); - - describe('relative get/set', function() { - it('should error on set', function(done) { - var file = new File(); - try { - file.relative = 'test'; - } catch (err) { - should.exist(err); - done(); - } - }); - - it('should error on get when no base', function(done) { - var a; - var file = new File(); - delete file.base; - try { - a = file.relative; - } catch (err) { - should.exist(err); - done(); - } - }); - - it('should error on get when no path', function(done) { - var a; - var file = new File(); - try { - a = file.relative; - } catch (err) { - should.exist(err); - done(); - } - }); - - it('should return a relative path from base', function(done) { - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee' - }); - file.relative.should.equal('test.coffee'); - done(); - }); - - it('should return a relative path from cwd', function(done) { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - file.relative.should.equal(path.join('test','test.coffee')); - done(); - }); - }); - - describe('path get/set', function() { - - it('should record history when instantiation', function() { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee']); - }); - - it('should record history when path change', function() { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - - file.path = '/test/test.js'; - file.path.should.eql('/test/test.js'); - file.history.should.eql(['/test/test.coffee', '/test/test.js']); - - file.path = '/test/test.coffee'; - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee', '/test/test.js', '/test/test.coffee']); - }); - - it('should not record history when set the same path', function() { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - - file.path = '/test/test.coffee'; - file.path = '/test/test.coffee'; - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee']); - - // ignore when set empty string - file.path = ''; - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee']); - }); - - it('should throw when set path null', function() { - var file = new File({ - cwd: '/', - path: null - }); - - should.not.exist(file.path); - file.history.should.eql([]); - - (function() { - file.path = null; - }).should.throw('path should be string'); - }); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/cloneBuffer.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/cloneBuffer.js deleted file mode 100644 index 34b3e7c1..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/cloneBuffer.js +++ /dev/null @@ -1,27 +0,0 @@ -var cloneBuffer = require('../lib/cloneBuffer'); -var should = require('should'); -require('mocha'); - -describe('cloneBuffer()', function() { - it('should return a new Buffer reference', function(done) { - var testBuffer = new Buffer('test'); - var testBuffer2 = cloneBuffer(testBuffer); - - should.exist(testBuffer2, 'should return something'); - (testBuffer2 instanceof Buffer).should.equal(true, 'should return a Buffer'); - testBuffer2.should.not.equal(testBuffer, 'pointer should change'); - done(); - }); - - it('should not replicate modifications to the original buffer', function(done) { - var testBuffer = new Buffer('test'); - var testBuffer2 = cloneBuffer(testBuffer); - - // test that changes dont modify both pointers - testBuffer2.write('w'); - - testBuffer.toString('utf8').should.equal('test', 'original should stay the same'); - testBuffer2.toString('utf8').should.equal('west', 'new buffer should be modified'); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/inspectStream.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/inspectStream.js deleted file mode 100644 index fe1802c5..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/inspectStream.js +++ /dev/null @@ -1,53 +0,0 @@ -var inspectStream = require('../lib/inspectStream'); -var Stream = require('stream'); -var should = require('should'); -require('mocha'); - -describe('inspectStream()', function() { - it('should work on a core Stream', function(done) { - var testStream = new Stream(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Readable Stream', function(done) { - var testStream = new Stream.Readable(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Writable Stream', function(done) { - var testStream = new Stream.Writable(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Duplex Stream', function(done) { - var testStream = new Stream.Duplex(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Transform Stream', function(done) { - var testStream = new Stream.Transform(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core PassThrough Stream', function(done) { - var testStream = new Stream.PassThrough(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should not work on a Buffer', function(done) { - var testBuffer = new Buffer('test'); - should.not.exist(inspectStream(testBuffer)); - done(); - }); - - it('should not work on a null', function(done) { - should.not.exist(inspectStream(null)); - done(); - }); -}); \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isBuffer.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isBuffer.js deleted file mode 100644 index 432ad2aa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isBuffer.js +++ /dev/null @@ -1,29 +0,0 @@ -var isBuffer = require('../lib/isBuffer'); -var Stream = require('stream'); -require('should'); -require('mocha'); - -describe('isBuffer()', function() { - it('should return true on a Buffer', function(done) { - var testBuffer = new Buffer('test'); - isBuffer(testBuffer).should.equal(true); - done(); - }); - - it('should return false on a Stream', function(done) { - var testStream = new Stream(); - isBuffer(testStream).should.equal(false); - done(); - }); - - it('should return false on a null', function(done) { - isBuffer(null).should.equal(false); - done(); - }); - - it('should return false on a array of numbers', function(done) { - var testArray = [1, 2, 3]; - isBuffer(testArray).should.equal(false); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isNull.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isNull.js deleted file mode 100644 index 356934a6..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isNull.js +++ /dev/null @@ -1,22 +0,0 @@ -var isNull = require('../lib/isNull'); -require('should'); -require('mocha'); - -describe('isNull()', function() { - it('should return true on null', function(done) { - isNull(null).should.equal(true); - done(); - }); - - it('should return false on undefined', function(done) { - isNull().should.equal(false); - isNull(undefined).should.equal(false); - done(); - }); - - it('should return false on defined values', function(done) { - isNull(1).should.equal(false); - isNull('test').should.equal(false); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isStream.js b/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isStream.js deleted file mode 100644 index 5cc0e0b1..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/node_modules/vinyl/test/isStream.js +++ /dev/null @@ -1,29 +0,0 @@ -var isStream = require('../lib/isStream'); -var Stream = require('stream'); -require('should'); -require('mocha'); - -describe('isStream()', function() { - it('should return true on a Stream', function(done) { - var testStream = new Stream(); - isStream(testStream).should.equal(true); - done(); - }); - - it('should return false on a Buffer', function(done) { - var testBuffer = new Buffer('test'); - isStream(testBuffer).should.equal(false); - done(); - }); - - it('should return false on a null', function(done) { - isStream(null).should.equal(false); - done(); - }); - - it('should return false on a array of numbers', function(done) { - var testArray = [1, 2, 3]; - isStream(testArray).should.equal(false); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/gulp-util/package.json b/spec/fixture/node_modules/gulp/node_modules/gulp-util/package.json deleted file mode 100644 index de479c46..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/gulp-util/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "gulp-util", - "description": "Utility functions for gulp plugins", - "version": "3.0.1", - "homepage": "http://github.com/wearefractal/gulp-util", - "repository": { - "type": "git", - "url": "git://github.com/wearefractal/gulp-util.git" - }, - "author": { - "name": "Fractal", - "email": "contact@wearefractal.com", - "url": "http://wearefractal.com/" - }, - "main": "./index.js", - "dependencies": { - "chalk": "^0.5.0", - "dateformat": "^1.0.7-1.2.3", - "lodash": "^2.4.1", - "lodash._reinterpolate": "^2.4.1", - "lodash.template": "^2.4.1", - "minimist": "^1.1.0", - "multipipe": "^0.1.0", - "through2": "^0.6.1", - "vinyl": "^0.4.0" - }, - "devDependencies": { - "mocha": "^1.17.0", - "should": "^4.0.0", - "mocha-lcov-reporter": "^0.0.1", - "coveralls": "^2.7.0", - "istanbul": "^0.3.0", - "rimraf": "^2.2.5", - "jshint": "^2.4.1", - "buffer-equal": "~0.0.1", - "lodash.templatesettings": "^2.4.1", - "event-stream": "^3.1.0" - }, - "scripts": { - "test": "mocha --reporter spec && jshint", - "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" - }, - "engines": { - "node": ">= 0.9" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/wearefractal/gulp-util/raw/master/LICENSE" - } - ], - "gitHead": "f6336c8ac9f52930b36ad14002cf267c06f801df", - "bugs": { - "url": "https://github.com/wearefractal/gulp-util/issues" - }, - "_id": "gulp-util@3.0.1", - "_shasum": "8214894d05c2bb6cc7f5544918a51ddf88180f00", - "_from": "gulp-util@^3.0.0", - "_npmVersion": "1.4.21", - "_npmUser": { - "name": "fractal", - "email": "contact@wearefractal.com" - }, - "maintainers": [ - { - "name": "fractal", - "email": "contact@wearefractal.com" - } - ], - "dist": { - "shasum": "8214894d05c2bb6cc7f5544918a51ddf88180f00", - "tarball": "http://registry.npmjs.org/gulp-util/-/gulp-util-3.0.1.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.1.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/interpret/CHANGELOG b/spec/fixture/node_modules/gulp/node_modules/interpret/CHANGELOG deleted file mode 100644 index 05e2d1c0..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/interpret/CHANGELOG +++ /dev/null @@ -1,32 +0,0 @@ -v0.3.7: - date: 2014-09-08 - changes: - - Add support for [TypeScript](http://www.typescriptlang.org/). -v0.3.6: - date: 2014-08-25 - changes: - - Add support for coffee.md. -v0.3.5: - date: 2014-07-03 - changes: - - Add support for jsx. -v0.3.4: - date: 2014-06-27 - changes: - - Make .js first jsVariant entry. -v0.3.3: - date: 2014-06-02 - changes: - - Fix casing on livescript dependency. -v0.3.0: - date: 2014-04-20 - changes: - - Simplify loading of coffee-script and iced-coffee-script. -v0.2.0: - date: 2014-04-20 - changes: - - Move module loading into rechoir. -v0.1.0: - date: 2014-04-20 - changes: - - Initial public release. diff --git a/spec/fixture/node_modules/gulp/node_modules/interpret/LICENSE b/spec/fixture/node_modules/gulp/node_modules/interpret/LICENSE deleted file mode 100644 index a55f5b74..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/interpret/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2014 Tyler Kellen - -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/spec/fixture/node_modules/gulp/node_modules/interpret/README.md b/spec/fixture/node_modules/gulp/node_modules/interpret/README.md deleted file mode 100644 index cd1b5407..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/interpret/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# interpret -> A dictionary of file extensions and associated module loaders. - -[![NPM](https://nodei.co/npm/interpret.png)](https://nodei.co/npm/interpret/) - -## What is it -This is used by [Liftoff](http://github.com/tkellen/node-liftoff) to automatically require dependencies for configuration files, and by [rechoir](http://github.com/tkellen/node-rechoir) for registering module loaders. - -## API - -### extensions -Map file types to modules which provide a [require.extensions] loader. -```js -{ - '.co': 'coco', - '.coffee': 'coffee-script/register', - '.coffee.md': 'coffee-script/register', - '.csv': 'require-csv', - '.iced': 'iced-coffee-script/register', - '.ini': 'require-ini', - '.js': null, - '.json': null, - '.jsx': 'node-jsx', - '.litcoffee': 'coffee-script/register', - '.ls': 'livescript', - '.toml': 'toml-require', - '.ts': 'typescript-require', - '.xml': 'require-xml', - '.yaml': 'require-yaml', - '.yml': 'require-yaml' -} -``` - -### register -Check here to see if setup is needed for the module register itself with [require.extensions]. If a method is returned, call it with the module. -```js -{ - 'toml-require': function (module) { - module.install(); - } -} -``` - -### jsVariants -Extensions which are javascript variants. - -```js -{ - '.js': null, - '.co': 'coco', - '.coffee': 'coffee-script/register', - '.coffee.md': 'coffee-script/register', - '.iced': 'iced-coffee-script/register', - '.jsx': 'node-jsx', - '.litcoffee': 'coffee-script/register', - '.ls': 'livescript', - '.ts': 'typescript-require' -} -``` - -[require.extensions]: http://nodejs.org/api/globals.html#globals_require_extensions diff --git a/spec/fixture/node_modules/gulp/node_modules/interpret/index.js b/spec/fixture/node_modules/gulp/node_modules/interpret/index.js deleted file mode 100644 index 96fa4186..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/interpret/index.js +++ /dev/null @@ -1,48 +0,0 @@ -var extensions = { - '.co': 'coco', - '.coffee': 'coffee-script/register', - '.coffee.md': 'coffee-script/register', - '.csv': 'require-csv', - '.iced': 'iced-coffee-script/register', - '.ini': 'require-ini', - '.js': null, - '.json': null, - '.jsx': 'node-jsx', - '.litcoffee': 'coffee-script/register', - '.ls': 'LiveScript', - '.toml': 'toml-require', - '.ts': 'typescript-require', - '.xml': 'require-xml', - '.yaml': 'require-yaml', - '.yml': 'require-yaml' -}; - -var register = { - 'node-jsx': function (module) { - module.install({ extension: '.jsx', harmony: true }); - }, - 'toml-require': function (module) { - module.install(); - } -}; - -var jsVariantExtensions = [ - '.js', - '.co', - '.coffee', - '.coffee.md', - '.iced', - '.jsx', - '.litcoffee', - '.ls', - '.ts' -]; - -module.exports = { - extensions: extensions, - register: register, - jsVariants: jsVariantExtensions.reduce(function (result, ext) { - result[ext] = extensions[ext]; - return result; - }, {}) -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/interpret/package.json b/spec/fixture/node_modules/gulp/node_modules/interpret/package.json deleted file mode 100644 index 06771e8b..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/interpret/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "interpret", - "description": "A dictionary of file extensions and associated module loaders.", - "version": "0.3.7", - "homepage": "https://github.com/tkellen/node-interpret", - "author": { - "name": "Tyler Kellen", - "url": "http://goingslowly.com/" - }, - "repository": { - "type": "git", - "url": "git://github.com/tkellen/node-interpret.git" - }, - "bugs": { - "url": "https://github.com/tkellen/node-interpret/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/tkellen/node-interpret/blob/master/LICENSE" - } - ], - "main": "index.js", - "keywords": [ - "coco", - "coffee-script", - "csv", - "iced-coffee-script", - "ini", - "jsx", - "livescript", - "react", - "toml", - "typescript", - "xml", - "yaml", - "yml" - ], - "gitHead": "df5960ce9d1bedb1fdf8163c96f70d92df6903fb", - "_id": "interpret@0.3.7", - "scripts": {}, - "_shasum": "18727eda04d50632ffa4b5eafb342b7ff398b36e", - "_from": "interpret@^0.3.2", - "_npmVersion": "1.4.23", - "_npmUser": { - "name": "tkellen", - "email": "tyler@sleekcode.net" - }, - "maintainers": [ - { - "name": "tkellen", - "email": "tyler@sleekcode.net" - } - ], - "dist": { - "shasum": "18727eda04d50632ffa4b5eafb342b7ff398b36e", - "tarball": "http://registry.npmjs.org/interpret/-/interpret-0.3.7.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/interpret/-/interpret-0.3.7.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/.jshintrc b/spec/fixture/node_modules/gulp/node_modules/liftoff/.jshintrc deleted file mode 100644 index 68710840..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/.jshintrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "undef": true, - "unused": true, - "node": true, - "esnext": true, - "expr": true, - "globals": { - "describe": true, - "it": true - } -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/.npmignore b/spec/fixture/node_modules/gulp/node_modules/liftoff/.npmignore deleted file mode 100644 index 9daeafb9..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/.travis.yml b/spec/fixture/node_modules/gulp/node_modules/liftoff/.travis.yml deleted file mode 100644 index e37da77f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" - - "0.11" -matrix: - fast_finish: true - allow_failures: - - node_js: 0.11 diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/CHANGELOG b/spec/fixture/node_modules/gulp/node_modules/liftoff/CHANGELOG deleted file mode 100644 index 7b919a97..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/CHANGELOG +++ /dev/null @@ -1,87 +0,0 @@ -v0.13.5: - date: 2014-10-10 - changes: - - Only attempt to resolve the real path of configFile if it is actually a symlink. -v0.13.4: - date: 2014-10-07 - changes: - - Set configBase to the directory of the symlink, not the directory of its real location. -v0.13.3: - date: 2014-10-06 - changes: - - Return the real location of symlinked config files. -v0.13.2: - date: 2014-09-12 - changes: - - Include flags in respawn event. I really miss `npm publish --force`. -v0.13.1: - date: 2014-09-12 - changes: - - Slight performance tweak. -v0.13.0: - date: 2014-09-12 - changes: - - Support passing flags to node with `nodeFlags` option. -v0.12.1: - date: 2014-06-27 - changes: - - Support preloading modules for compound extensions like `.coffee.md`. -v0.12.0: - date: 2014-06-27 - changes: - - Respect order of extensions when searching for config. - - Rename `configNameRegex` environment property to `configNameSearch`. -v0.11.3: - date: 2014-06-09 - changes: - - Make cwd match configBase if cwd isn't explictly provided -v0.11.2: - date: 2014-06-04 - changes: - - Regression fix: coerce preloads into array before attempting to push more -v0.11.1: - date: 2014-06-02 - changes: - - Update dependencies. -v0.11.0: - date: 2014-05-27 - changes: - - Refactor and remove options parsing. -v0.10.0: - date: 2014-05-06 - changes: - - Remove `addExtension` in favor of `extension` option. - - Support preloading modules based on extension. -v0.9.7: - date: 2014-04-28 - changes: - - Locate local module in cwd even if config isn't present. -v0.9.6: - date: 2014-04-02 - changes: - - Fix regression where external modules are not properly required. - - Ignore configPathFlag / cwdFlag if the value isn't a string -v0.9.3: - date: 2014-02-28 - changes: - - Fix regression where developing against self doesn't correctly set cwd. -v0.9.0: - date: 2014-02-28 - changes: - - Use liftoff instance as context (`this`) for launch callback. - - Support split --cwd and --configfile locations. - - Rename `configLocationFlag` to `configPathFlag` - - Support node 0.8+ -v0.8.7: - date: 2014-02-24 - changes: - - Pass environment as first argument to `launch`. -v0.8.5: - date: 2014-02-19 - changes: - - Implement `addExtensions` option. - - Default to `index.js` if `modulePackage` has no `main` property. -v0.8.4: - date: 2014-02-05 - changes: - - Initial public release. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/LICENSE deleted file mode 100644 index a55f5b74..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2014 Tyler Kellen - -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/spec/fixture/node_modules/gulp/node_modules/liftoff/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/README.md deleted file mode 100644 index f490d0e0..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/README.md +++ /dev/null @@ -1,301 +0,0 @@ -

                  - - - -

                  - -# liftoff [![Build Status](https://secure.travis-ci.org/tkellen/node-liftoff.png)](http://travis-ci.org/tkellen/node-liftoff) -> Launch your command line tool with ease. - -[![NPM](https://nodei.co/npm/liftoff.png)](https://nodei.co/npm/liftoff/) - -## What is it? -[See this blog post](http://weblog.bocoup.com/building-command-line-tools-in-node-with-liftoff/), [check out this proof of concept](http://github.com/tkellen/node-hacker), or read on. - -Say you're writing a CLI tool. Let's call it [hacker](http://github.com/tkellen/node-hacker). You want to configure it using a `Hackerfile`. This is node, so you install `hacker` locally for each project you use it in. But, in order to get the `hacker` command in your PATH, you also install it globally. - -Now, when you run `hacker`, you want to configure what it does using the `Hackerfile` in your current directory, and you want it to execute using the local installation of your tool. Also, it'd be nice if the `hacker` command was smart enough to traverse up your folders until it finds a `Hackerfile`—for those times when you're not in the root directory of your project. Heck, you might even want to launch `hacker` from a folder outside of your project by manually specifying a working directory. Liftoff manages this for you. - -So, everything is working great. Now you can find your local `hacker` and `Hackerfile` with ease. Unfortunately, it turns out you've authored your `Hackerfile` in coffee-script, or some other JS variant. In order to support *that*, you have to load the compiler for it, and then register the extension for it with node. Good news, Liftoff can do that, and a whole lot more, too. - -## API - -### constructor(opts) - -Create an instance of Liftoff to invoke your application. - -An example utilizing all options: -```js -const Hacker = new Liftoff({ - name: 'hacker', - processTitle: 'hacker', - moduleName: 'hacker', - configName: 'hackerfile', - extensions: { - '.js': null, - '.json': null, - '.coffee': 'coffee-script/register' - }, - nodeFlags: ['--harmony'] // or require('v8flags').fetch(); -}); -``` - -#### opts.name - -Sugar for setting `processTitle`, `moduleName`, `configName` automatically. - -Type: `String` -Default: `null` - -These are equivalent: -```js -const Hacker = Liftoff({ - processTitle: 'hacker', - moduleName: 'hacker', - configName: 'hackerfile' -}); -``` -```js -const Hacker = Liftoff({name:'hacker'}); -``` - -#### opts.moduleName - -Sets which module your application expects to find locally when being run. - -Type: `String` -Default: `null` - -#### opts.configName - -Sets the name of the configuration file Liftoff will attempt to find. Case-insensitive. - -Type: `String` -Default: `null` - -#### opts.extensions - -Set extensions to include when searching for a configuration file. If an external module is needed to load a given extension (e.g. `.coffee`), the module name should be specified as the value for the key. - -Type: `Object` -Default: `{".js":null,".json":null}` - -**Examples:** - -In this example Liftoff will look for `myappfile{.js,.json,.coffee}`. If a config with the extension `.coffee` is found, Liftoff will try to require `coffee-script/require` from the current working directory. -```js -const MyApp = new Liftoff({ - name: 'myapp' - extensions: { - '.js': null, - '.json': null, - '.coffee': 'coffee-script/register' - } -}); -``` - -In this example, Liftoff will look for `.myapp{rc}`. -```js -const MyApp = new Liftoff({ - name: 'myapp', - configName: '.myapp', - extensions: { - 'rc': null - } -}); -``` - -In this example, Liftoff will automatically attempt to load the correct module for any javascript variant supported by [node-interpret](https://github.com/tkellen/node-interpret) (as long as it does not require a register method). - -```js -const MyApp = new Liftoff({ - name: 'myapp', - extensions: require('interpret').jsVariants -}); -``` -#### opts.nodeFlags - -Any flag specified here will be applied to node, not your program. Useful for supporting invocations like `myapp --harmony command`, where `--harmony` should be passed to node, not your program. This functionality is implemented using [flagged-respawn](http://github.com/tkellen/node-flagged-respawn). To support all v8flags, see [node-v8flags](https://github.com/tkellen/node-v8flags). - -Type: `Array` -Default: `null` - -#### opts.processTitle - -Sets what the [process title](http://nodejs.org/api/process.html#process_process_title) will be. - -Type: `String` -Default: `null` - -#### opts.completions(type) - -A method to handle bash/zsh/whatever completions. - -Type: `Function` -Default: `null` - -## launch(opts, callback(env)) -Launches your application with provided options, builds an environment, and invokes your callback, passing the calculated environment as the first argument. - -##### Example Configuration w/ Options Parsing: -```js -const Liftoff = require('liftoff'); -const MyApp = new Liftoff({name:'myapp'}); -const argv = require('minimist')(process.argv.slice(2)); -const invoke = function (env) { - console.log('my environment is:', env); - console.log('my cli options are:', argv); - console.log('my liftoff config is:', this); -}; -MyApp.launch({ - cwd: argv.cwd, - configPath: argv.myappfile, - require: argv.require, - completion: argv.completion -}, invoke); -``` - -#### opts.cwd - -Change the current working directory for this launch. Relative paths are calculated against `process.cwd()`. - -Type: `String` -Default: `process.cwd()` - -**Example Configuration:** -```js -const argv = require('minimist')(process.argv.slice(2)); -MyApp.launch({ - cwd: argv.cwd -}, invoke); -``` - -**Matching CLI Invocation:** -``` -myapp --cwd ../ -``` - -#### opts.configPath - -Don't search for a config, use the one provided. **Note:** Liftoff will assume the current working directory is the directory containing the config file unless an alternate location is explicitly specified using `cwd`. - -Type: `String` -Default: `null` - -**Example Configuration:** -```js -var argv = require('minimist')(process.argv.slice(2)); -MyApp.launch({ - configPath: argv.myappfile -}, invoke); -``` - -**Matching CLI Invocation:** -``` -myapp --myappfile /var/www/project/Myappfile.js -``` - -**Examples using `cwd` and `configPath` together:** - -These are functionally identical: -``` -myapp --myappfile /var/www/project/Myappfile.js -myapp --cwd /var/www/project -``` - -These can run myapp from a shared directory as though it were located in another project: -``` -myapp --myappfile /Users/name/Myappfile.js --cwd /var/www/project1 -myapp --myappfile /Users/name/Myappfile.js --cwd /var/www/project2 -``` - -#### opts.require - -A string or array of modules to attempt requiring from the local working directory before invoking the launch callback. - -Type: `String|Array` -Default: `null` - -**Example Configuration:** -```js -var argv = require('minimist')(process.argv.slice(2)); -MyApp.launch({ - require: argv.require -}, invoke); -``` - -**Matching CLI Invocation:** -```js -myapp --require coffee-script/register -``` - -#### callback(env) - -A function to start your application. When invoked, `this` will be your instance of Liftoff. The `env` param will contain the following keys: - -- `cwd`: the current working directory -- `require`: an array of modules that liftoff tried to pre-load -- `configNameSearch`: the config files searched for -- `configPath`: the full path to your configuration file (if found) -- `configBase`: the base directory of your configuration file (if found) -- `modulePath`: the full path to the local module your project relies on (if found) -- `modulePackage`: the contents of the local module's package.json (if found) - -### events - -#### require(name, module) - -Emitted when a module is pre-loaded. - -```js -var Hacker = new Liftoff({name:'hacker'}); -Hacker.on('require', function (name, module) { - console.log('Requiring external module: '+name+'...'); - // automatically register coffee-script extensions - if (name === 'coffee-script') { - module.register(); - } -}); -``` - -#### requireFail(name, err) - -Emitted when a requested module cannot be preloaded. - -```js -var Hacker = new Liftoff({name:'hacker'}); -Hacker.on('requireFail', function (name, err) { - console.log('Unable to load:', name, err); -}); -``` - -#### respawn(flags, child) - -Emitted when Liftoff re-spawns your process (when a [`nodeFlag`](#optsnodeflags) is detected). - -```js -var Hacker = new Liftoff({ - name: 'hacker', - nodeFlags: ['--harmony'] -}); -Hacker.on('respawn', function (flags, child) { - console.log('Detected node flags:', flags); - console.log('Respawned to PID:', child.pid); -}); -``` - -Event will be triggered for this command: -`hacker --harmony commmand` - -## Examples - -Check out how [gulp](https://github.com/gulpjs/gulp/blob/master/bin/gulp.js) uses Liftoff. - -For a bare-bones example, try [the hacker project](https://github.com/tkellen/node-hacker/blob/master/bin/hacker.js). - -To try the example, do the following: - -1. Install the sample project `hacker` with `npm install -g hacker`. -2. Make a `Hackerfile.js` with some arbitrary javascript it. -3. Install hacker next to it with `npm install hacker`. -3. Run `hacker` while in the same parent folder. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/UPGRADING.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/UPGRADING.md deleted file mode 100644 index ef31983f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/UPGRADING.md +++ /dev/null @@ -1,26 +0,0 @@ -# 0.11 -> 0.12 -For the environment passed into the `launch` callback, `configNameRegex` has been renamed to `configNameSearch`. It now returns an array of valid config names instead of a regular expression. - - -# 0.10 -> 0.11 -The method signature for `launch` was changed in this version of Liftoff. - -You must now provide your own options parser and pass your desired params directly into `launch` as the first argument. The second argument is now the invocation callback that starts your application. - -To replicate the default functionality of 0.10, use the following: -```js -const Liftoff = require('liftoff'); -const MyApp = new Liftoff({name:'myapp'}); -const argv = require('minimist')(process.argv.slice(2)); -const invoke = function (env) { - console.log('my environment is:', env); - console.log('my cli options are:', argv); - console.log('my liftoff config is:', this); -}; -MyApp.launch({ - cwd: argv.cwd, - configPath: argv.myappfile, - require: argv.require, - completion: argv.completion -}, invoke); -``` diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/appveyor.yml b/spec/fixture/node_modules/gulp/node_modules/liftoff/appveyor.yml deleted file mode 100644 index cb89fa74..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/appveyor.yml +++ /dev/null @@ -1,28 +0,0 @@ -init: - - git config --global core.autocrlf input - -environment: - matrix: - - nodejs_version: "0.10" - - nodejs_version: "0.8" - - nodejs_version: "0.11" - -matrix: - allow_failures: - - nodejs_version: "0.11" - -install: - - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) - - npm install - -test_script: - - node --version - - npm --version - # power shell - - ps: "npm test # PowerShell" - # standard command line - - cmd: npm test - -build: off - -version: "{build}" diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.eps b/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.eps deleted file mode 100644 index 8181f0097cffe0eff8dc959f9be3cbe64a82014e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 520682 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

                  UBMIEcFt$MWix%<1%nGCgg5N4V0Z{bMrVxSXESV0 z*D4cUO=@Ev#A>qrdO-STf2qvcj{J{61-8xcj3>yc`2viyA>UWuwDb{u-%~YnW6FPL zOu*~G(fd%9I;6SVD@D-G)&1(BO}ozM)9(Eay^B>EpqXFm*Lm3g4VD--O*A?C6=cwj^Zf37bekzuOkgSL1|3;Iu|IBBx=_q>YdlUwWT1>tkJd@FS} zsjm1RV;1At<(T{6d<*7eR?e?#8Sba2*rd;)9$=ZXXMMC4#{QUtG9oxJELm!p?7@QMo| zis4GMZ_4t5wrJ>H=bNSt^B{Nm2eo8nl4U6j9YAE5Smk@Q_H7Q80tLw>t2)=T$H5au zGh1;FoKWmoB}^vXn;tVsej&s3II};_UVKgcrQCNPJh76hMUpA^kMO=c>6}%lZ0L3F zkyA&I98-Jo=N8J?q}mM8?k;ymtD~F3|L_AjokH-KLub)8*@dI9R2K^q`!pUspVdD) z_pJAmHkAZ@d>{EukYOIP?Q69bKnWSED3%&+r;9V5?WgQ%TOaThuJmpiPH!NlE#e+4 z=~Al?Hi`R!9#4it=(wQ{V-CNYE3oauM6ls2LW$v~LfRmr+U;g|(o1fC(c{8U6AOe5trPSvO z=P%WIj9=!44h}^DZ7=TBZKE_l_+87Ehf^oF_}Hw1Y}SrCuiV7o8lTe-$e8WJx>bc@ zs``pmDLU)jek zE3G|xh(Q$=J*mK#ecxcn?|Bp32s=`*sKeXxx+b30MQkX4d6J$M9bK=? z1~ed8hps<-wt~ZteMMJ7|AD{KI;pdN9D$Yufjmz|L3hm-$Ou;5U7;hn zQZ%dPs7%ULdQvl^wfkc+P+#qmXgAK@tMJ41*8SFz86LtgSDbH`S?ZVB4AP8!=#hsA z!d&^POMnNL1wZqReamDej^-P#FErQl)c#KHf5T`yA(n5>uYbmc&O8q9NV^9?LBA>a zSR7ZiAQXz~Rk93|y<8IW{w1@4J$;TjdZFxK%LA9yHdRKYX=QYsO*ZHp`F2t^r7dq> zi}9d#Z+H!jT1(yvGKllsuGTojr#v-k78~zsak+V$4q$O1*hCwSSsZnpA{kx_ykFy1 zrA}0TS&PGHH)&C-Ap#ebN3?{TCZu|K($lQaps@0xtIEcs>J}rCQuS?j9Gm=|A77A-2_R^x2kb%q8Xh{kM^;2CpEES+ zSHcui6_O#l%&odX?RJ=MxH2B*B7U#y!?`jPFadfe(n>4i(uCFVQ+FSgKz`T7@F_&P z+Q(lg4}?YE2ZMj3kosf+=9X+_W>q23aU47Xc0N&F+=mQfL$ex=5bp0Yy?*dBP!f-) zB;~JDFiA|^cnwH(9yYA5*2T~p=jmri7i`-% zs{ZC^-W;5_J)oGSji%bp?OTV#QJF87?=5smlT`xPpGjP=RA-cQQTC+JROK?=tninb*Oqo#;-#yp+5sM(6;0P(LZQj)#s(zcp!ji|4ya zN2y5MV^{r3o&IK3`YX&u>y_?%_&g@4C3fjAmdxa`lx{s6?tMM(xf+n|A7VyZiXdUx zs5Ozqs51G?N}Q1fL~{U?jw73VV5NNYw_6QVsJ|_S}wfzYvo#X z|E1>3%*&Q@$f;t4{ngCLBx(<+s&G z#%IKU3>j2Sy|yC054S3eO+LBV;PM4V@NS^4u2W;HA3OPPJ#(7Z-C)YLIb0l4w*TUL z(#xj86~AEaa^WmOI{6yQ&D+7SNqg!8&g9kK;BGqG)!lgCAf5zfk*hXDzB`c~rFkhO zLOKp}?305)H($zcMjO9C$m2csPOJbCL0m{3yGs~;gim_Z>#jCAwIx^$y$(&vyt!VT z+H4ulu~v~t8@*`#H|)3Z`49ph)0+E*%MoyFGLxuwI@29$!f1|L zzec53b-5b`gJxr4_MT8(EKTI80z|YiT`ryOYmMF<2Pw5Z{PKxIuxPTKyQ_}!)^K&O z`~I~tr{#O{;U3Ei0An($bKS@SV9p9O1$;Tkji}(p&#^&<^;tD?JCeEQG^qLSo0p|; z=$r$RN;lBE=~*ZiuGy-O^Hz?)= z?8+-w|2EB|qsqPfA}%C6Rg>cn*=-gd4Uh&_>1_X!Tn6-fuC!T8#o}!_ACh-D|JlBN z!_T?>kEc`!c5%N%z%~QXUy=O8qWg1->qot|YX|QS5Masm_fgbNt;4=D-Qr23D7HD| zjB%^Q&6OCxMCLo^pw@C*3f$0LhU(-x^sy;)5fnda=85UR{W7h9NfFYsN%umrf4hNv zoD=$cKN4RgQk>Mc^{BQiw)&`8)n*W5P}?dlBJDb@lRZj+@B0%X@S2rBQoe0mVg+uo zKG5QJ(J&(B;m9PT-1jg86#*aO#3TLgD5kk>EXVcSEIMy>0vScT+*0ZD8^)-U|m%hHzPz8@*Ole%<&3+nmtb=i%_Jm^t*XpH&dh_E^2a z^3(pEb3kDFi~U2m zaB(*-D53)Um#&rj`Nj5rPpWas)^{ZORJ^HV`(7*h8&C&Otn&MhA-ZMea~)rccd4er zf`NYg#4p&uMWzzGzvC}ee2ltGI_Z0}rDvd5@H5nZ%m@eR(HU;B7ZxQ`s?j20Yn~7# z*D7rcl|~@fs@@ap_oSiCsk5}BH_=4ILp)-B&BpsZSiE39>%nUMM|^ z`IQe}2W--|QLtyyd&{rs=&^d;F#-w8 z`A)RCv?$`t-f5g3Aouneb%H5X&8%Zn`ZJ;G7hONyF*;`FgmyL>CWmVw#@X+D0`JQT zEjz_~`TPN=%+grt>ztyNr00=d^e%h&E1%gy15H?7=DX>OFda>%!Dy}=N2}UgtHl?)r*MC}ef&4> zxYeHw6rcrleVBQLD{xi%Q$w0_j~DXZX%}y1axq5jeuFsus7oPb`&Z|k*oL&tDh#BI z20C7Q)cx@prf_}rlMB{R!+(x#dA}Cf9DyNVk4clR9y|`Un_8@=2E{?j)tQc134FLMxYXEJ`6ms^sOeoZDIw_w&(G7V7330Wjd#7j-bkS zs2NRznN8o=;$BT^y)h?mF7t^80>@ksH?{}JDeG8=VWGP|Q;Ye2)GkH0R-tUP3&sIz z7{6k*z2@MFq)ThZKh`VsuAf$ryX3ykPHSLUsv(9i+G?W2_%m6C?}NZl6)WL3(x}Uw zcC&6~qYFs*QqJ|$t0#z~eBZOG+i`uYC{mLpdgvI`>9qAL6}L|dt{$+JFRFZ|494P) z+AJCFpe?l9d`~S1(%|yIjJc(v9QWV5k$^eGCGJlu`4{OGej1CL2r5X8=cMq(tv%Z z;vYN?;<};;m-4&WCLvAdJ1v08?zD>lThoQ`YO2;kXAUFc6^=Fg{c?NZJ=eMjZR=Gs zOOIVg|8B3Gwz=lB^+I*00|9A3$7hZjuP?xyn%RM;W;a7m{jvKpd%++_{08+cI9K_~ zE*L&@`(OKn=OfTEJ+F(v{$t0um){rxcE!bUIRvtU^lHq7XTr~gy+07LZ9O9j&in`6 z>-??17F6KtrJgeFYFbYykl3UsS`tJA_TDc^SWoWp(#i;a`WGvQvR12Zn&b^)vU8Qn zP5;JDM_uLd%3t}QeAh5auBp-KlmMBk8JzyOhxLzbyS46n?*r{_Z|A>4*c?u?-WB?t zld=e#Q;ly*iyc2N@q^mIiv?sda#M2ouNQZgDy(@$VM)rGxlINhd=I;XNO?Nvsm&UI zuW#2!6L(Yry4Tf;Em`tBvW#aje@t`lX0#yWEtK4kHcypL``MqU46#oF4d;|GoFmoY zx9`jIFe=$mf7(Nd;!V=GWS@E>Sg(PSuV}XSejHW1Iq|8|#SIdkF>5ME20~2i)P~2M zGl8RSi$-I_>j+TtNTKeiC6pmzZx3@6MTXnsF$;V}3KcZo{tJ*f$oO*%iL=^Z=MBV>HD_-&5A zBs;2R~GFiZ4Z7g+j+>27P{UA>kmHln=zef5^1WWosN6Ai6i+q@cE z!OZpopeqiW0my2@2J4z9^SFJB%|;XvD*ih8gg`pUtx3f1HHKk3*SrPSVu7+mc-gx5 z7TTrhMcJv^wX=BL8Qd2(y!YcBXs&C4X_O0Z#OZLGle%jrJ2BVlbFL%L4@_&hVKG(d zlecQUAYb!QzC9wH`t_5}_fe;fBq!xTLGK>iC)a73)IcItIlZKC`v&S!Dx#paebw8e z$`0Jupw7Za#dz(XpSV4GoPDGE3ef3hQ#}-wr*^A&`roKl?+}~MTul9M|1`EmKs-a3nT|jqI^6F`V z#oUtUlTE)n+!_WU)(=^W)+fD&Af1srf1)I=ekf8U>?vMA2YapCfm!ZSX47cQ7n8o# zzWs$e-4-F&2AQOqy(OEU?|3pY=Ov-a6%x%Rm!ZJjD&cxolkr7!YhEkV zM)4i&q{E3x>CCe5z}0AUZb~w4VePVj4Uf9YlT>MKh6YADJ(+Q0l+Fw!2@siaWmELFG*(SXE zD|%+_7HizN4<2-Br8M^l8HQtG7A;qkfD(F4cR^P0dv~Wkzo*(~x^M5@5#AU2~|+fUbfx6>_`VUR)mvWEMD zRIOciP?7JW-HiZG)S!hniuFR_e$xAkX&(k?=cCeV!a@xzETn&P%Wr4%6NYkS#tBu1 zF^n?sB>{OlbA}=X%Z0LCnBgqj0)@*%^>L&_w5UyJXfkLAkBvG#inDnnHm3BexSXtb zZy2cuuC}+5&(_z*JgPQUa3;4ea&*3*Yq{RI0+^Uwd{!pHku1Rwcl*esF--kM>d!Isk#*Mf}4dAKP>h8UkFRdPmegMCoEUMG`24P?_a-%vfJ`HY;k z<=0s{y+db_M)6ActDYB<0_Y@Y>fpNP4x2sr>EE3y-$xWfab|p%?XjZ6+_SU8#bavw zYNFT8JA2zmT=JYIl=n%lJUVM<-Y`R@DmGgc%#= zcmBqP2KJR`ByXW-IF_mTQXB{t3TNT(I=+v2b;?G9)<5#N;CUjdkXuGL+zBV|0-@y$e|tzL4jl z&%)|9zUak9w9@B?>abwx`a$d8E~*ydD0Je3(lJ?-D}!}YI=>gsaMSNnXGN@+_&c2A z*UR+M=zfedwfZo?7Ufdq2*^{qQt|s?Vxl^3{vIWB`%C&blD1z=%D?ItBaoyGT8wsPH|yM71nR zVQ=6X;R2(wRgXJjOhJ-wJ8Nk$3S~9*QsOcJZ4$+z^nK2wa3J;cThe|#Hxdp#^7xX2 z8Lr>L2S-7&+n-lx9Oi4@#pl=8QU)s8opIN&O+T2_ZpDwwO9A;i-52GWH+V7yHT$-= zr?dZKuAMzN9q~r^bSvv#8wLFbsg}ulehn%DA$Pv3jGHfV_i2!BAb4{f+w*-(nj>;CKhwzYb0Bb1 z(8t-dlPyOTTY257gR#_!(Do06{_0*{kRdgs?qq7E69-R zAg!51A7`ID4Hlpvbe!~GFP0;gl{%)m*FaidRu?Cp6%IQ#pZ-lJv!l1Z22`fC(|Mnw zPKQg_=EmRNsBN^mZpYZ&0)ZA@Mdgo8H&=bNIM1D@{u1PAxi0Q1Q7g0KdHRXI@K*Ns z8XivZ$L7tzjdDckD5A(7n#cEC8pt|50_pMK7V?TK`d zMnaCMPb${n?zM&b{94SFoA~v;14?Jm+t(c|hhXP}fSH8Wd#F0a9A>JyP=!V2eoe-n z_0OE5?GFDKcN*Oa+R5#cXoC&>Wc92HFdZ>{E$Gef0{OhEn$cHXIZWrlqMYpidPH<- z>~%_w-mP*vUatO9&ee94_4+qywl~ZQmMUA@CjbY=9*1s$hrdhpxONgYcr&nKGD5n~ z|6GrWvquGzRqt8cO!;dDVM{zZxUgM9ieOvKX{boka6dw*Dd*L1BUI`c`Z8Y-==Km zUV$ea*{$=MQ7A7I)`DW+B>y-n<_n0`&DQW=;XTY?k+D00O~Ro&Y5%4{*x^^p)p~9{haHcTf#;VUN8rCimw-% zTFcq(<>9F3mSP}-vdL3mHGz!b#hy0|Iw_6jqQ_vBMjO5{Y`f22#`{Qm(XHD8Uv~$0 zeD#hAyp9yx;|6K}mF~t)p54jUbzmAUOOCT>G556MSO|OwwXkl-Vm3+vhOZ6vn%-^o zHChGCfO={4aDrE~e`)dqw>ckz?PXYmNo!})-z-jR%(@qx^@E!>LM$BR)sy_X^IrPkH$9>T$Eh=}I*&$@BNwZ=};O7M&!)7!a# z%YX9|ImkDD%JI7{oun(SkEjjP_4mCV)@yH$q99(T^Ig9z7w0SG&jG>vx#4WZyR+~P zZe8R?#iXiI#>cOIuSg1$5`A2*eSdUD*-$Bca`y1u+{v*6tNDNJ0od%G8=|B13A@J= zVkZ*px!at=5UaI5V&nP(^98J)pr?V1zaY1-!2Gq)@=NGjb@F+wq;vJW-k_V`0Jo## zrMzNVGAJSE-QzX~3F%ZHYu21dTRJw?&Q(EP!T63)TjqZSzvoq=M2EQW?IXMcrN$pX zqw8*Gn{4dB3b73!f9}>=Y*gv*d|d0N%g|_W6MHz^zsK(h zB-e+KA9m`qlTeT^lX7tb3Zl|X{F#e+-vrYsi=z9x7uByjt8YYKvpt*)SfO5MyvTZ?V#0BxvgT8muPdZTSx^;^sR&CbPtEyPxy@QuOd z#w+ggfmPj&C*LX?X5u;gO;4RoL(E;)t)@vlU`BsgTN+Jddq*vA7sr0Tv@Xsn&9Dv| z=}q-I&3!h7U1>JhmR675rVM_HI@r_Gpbv?*A8@8DTTN|0a;5!>uaVicwDuvjXRxE3 zjn#l>m%a>Y!@}ywbcrnFRkAy>_v;cf>o5A=l1jW&S|9v9oZd<;D$IVRmLWDEUcO%= z#ec(c=ML>EY^>_#8*vWm?3g{+e|~kH7yi(B1@6ACEq3Y#wJ_y#cB55bo96O}5-^&T zJ2eI?EGuM?p*o#xuJaRS=-55w*jweK82&2TA0N}oxPJ@JkS^y!1zYIJ$f@p)*AUqH zn<){}bk5^t?>t&`cl~2r8YvL1^OF%?wl+(*^yz%ygh;B7eCJ_}eA!vn)}^ZBn-#Tc zOh=9L9a&5xx|Ck_Sfm^kA&CCD(y;c(tW2g5Ll)~x>TZ0Yi;vN3njt3a$gd4@G{1Z| zO99F|Klsw`at68IN=3|Lf68=Q%(UR{FO$BX$>UF^}F^#;C~y)W8Q`F5yPIRC*WKT4y?RW} zrl775`OkAQ?@Y6cM{FM7npv>oOIwL5q~|?*GztVN#hn~iJ#!$_v}}2R&8<9iG*K9) z2GQ|fdpzscEV`4R{2@L4?daae3YJr@BhSj>FP+z6`rIKsEQ&j@?~~SD$meLjq{(eA&snu>1ifa13kWgD;?F&vn^goCqgfsa|4tHM|?3!jgUR*LUYr%l|gdVmw+@4{6*-F zz7wMnR*NhX;?eI?n2)e$O zQHj)5p`qj)rZkIAkK1!0#f;AC)V*C8hCUQbf5-jdyDuP%?NNa+in4RMG)AY{qic<8*hSi}>r5pKnB)+J7q?{e?Sm9RG|I(~f_pfPv(kW7f{b`r~(i;z+ z(uTVA#-Q%F`gKa{MZ)%dXkOOFTZf_=Dzwqr@3ICALXWZDXbCH7TDDJUQEq-0M2Fyh zZ?-$G^e5Pw_H45)4I4c|n;en{I9|$cuL(@qeQFFWH*ohT^e+)$hL>p5yL@@lt=-1u z!E#4Qj!~e|UsW%f?Nz!*IDuf^rG$z`(XI!k(eI=|xgJ07hc>ze^XP9f+!Qt-=fLUSc-L%uc*lGRXJ15z!r&ZZx{vRmPIl<7KJNKu_$eNf_2~Y$Qmpp*Iq=oy z>Tf@shU)gzgIlMa^Qs?ENj4WQG0CLcffMfM?Wk&^=K275VWU`IcA4i@la+mg@K7v& zo{buI3Mb558lpig{$*=6`N~*?o=42PDGdU4g>sPh=oaGY&aDh@uYx^ZWoD~&jMe@o zmSJ2Ek$N2#V(vBdT)z~-1iM>GE0ThN>jCL3TTctW%ShgY&3jIs7WM#=;%a;?J%h~( z-0kMr%ijJvWK%CimrPgs=|w|dt&b{IVVJwr_FX=u29C+cDFEZPFGy1A&~~ zRS%3d&a@#Ls*r-((_mwjY!@%fB=UJ|y({uJoPS|%qq3~#IEUDweSJ~*aPF#nxHWQ! zchQB)qNi!(l8IXRGe+I?a6n^d&280>Cs6#d9eUf+^PLwOJLLnTw(#f2D_Z|l1VdEa`u6K)b^C{Mc3v4_AYXc*H!qdRMPu~( zG=FL319_)x)rLMAUvz~w_iSUMH9B}fn$fjLwp(&DPyLG2AOf^BIl-ErdK=zJ;ao;QX7}YkI@e1Lc>YIq}0L5IWU72lH|-Sav)Hj1dozNy~f8f zsuzd)aHV#y3y3&~Nb}r{PuF%?bY<^X7$wz87rL`_;OJS*C{=C`cA>;Gm-%h4-)dfP z_m*(sntWkMJZQE4aYr|^zj^ksp(4Y3=C#$YDPpMTBB){WujXfR>^o^8XlF?D3Fr8Y z(I@_1tbDGp?lmuQyO#H(ccAN8aUXp?$joJoWWIeU-jGkz0i;f<-jIUd#dE`ggt+-~ zf2=~Rx_D=0%er3b$rK9YZl56L6jx2oOJRBIe)>a?Dr`rIg}k0<@`v@yfC!$xU(MG( zXCB#SVW1y?Ma*AaF%r1FJ)^i%=MJA@bm<{EYji%PRO^h`mf}^0Zg#sa^XR7c;khTo zcBt)2#wvPi&)>N7Qp~i@*MoHFj(9*Vwxx@?jPsRCJiL#a`_&$~Jo)an>Pm=m7V3Gu z54ELybkW`^5=*`L@u?j<{c0Lazm=b`4e!6esfTQ?^3|^o<44xm6YFM|DaxO*0UiF` zcY$69|2`8+m)&FWJH6QR^C~q0QmV&N-SjHYv%p{-xRIr}!&`|iSk!y;p5AAZU&6VI z*`=@(u?DgBOG$HKtRClx0AoaL#$VLO`}{Y$p1sZQ-Fgi7-con677?r?CL~9t`=RE);#j!O>qlW-N8cRW$hQv2)IaZ6 zwb6z6>)QUgVRr0?BO%pOlr50k?KDV@LOo`=&bT7RE*AaP;(G`h*hwz1$&wn#&j|p% zZ>r-W*k-iqiZBhp%?~_kRr<7cuzz#@KtA0cuWhot=~a?wjwc9mJ6&=*N}S#{x2lwR z;*B$1@q!&MU9>p)a~So~c1w$Ie|WAw@A++=9YSPO_(MCrkrJVqP+^l%R&5g% zV5|wd*VSoqKaBa-bJ!)c--d38f9LjBXpDQUQw>~Pxoo-WU{?O?s%q8Po5oROzIxl zA`CuTDFoq`kN09S&ET%Ah0$Gt#JBUSo?6?W`x`DEJub00ZFd^~YIE#>?|&FFxMq2| zxQdIqY+W`(2A)P}fyh{b z>>1BNQiO=N1`sH2hwrO7Vuf0J zM}Mo={_qzRY726*9u|`}`^FsOk^ev>@~>0$Rv8^^2Aw0!le5Mp{Jy1bXKc2lb>!PM z5SL!>%`DG8Ta_HM8l1dQ>GfnxPp#)3{}A-I7p`G<)J0Zwjl5I`r`b@Q#I@{N)ecd7 z5N6ShkjdII1(CpT(cFWJ^DT`wt9oI*pFJD*0lpFhe6=g^9!$4@xel%h?Ay2&Hm(Jd zmT=>^GE%H->+eowedf`8+%Bc&6CfH1^69tQGdC{;MvhvIne|DlnL{OZ_C+6dNrhMW zf#>e;tvF*y;A#N8bA19x$m_9seysBIphJ{rC)|3E_clrW5cxF5Pg(6y-z(R^|5|}p zQQ2`oShZ7=e%YtedPsulk?$^yDe(6y6B#O48oQRaJ1~{biA-pnA3;xQlh zzDYiriani?4&gob#0;U2@qaBb8Q;|QoZgQV~e;_&^IQCS?gYrfm1Qw zZiqj7(}6AB>aV^bLe~d}9cm+vLAuPA`MhK&b z-b>2m^J90GxMF;8N8ml8l4tjJCP%Qfs{;>Ss{&PtFxb~ko_+hfM!+yT2yusb@*iNmBzf^p4^+R&?nD!LV92QeXq3GO3axHv_e$h zZ6nMJxr^Q=Vidb|ZVppGQ$?uMe*phcdt8%ovsax>LMT zy>jk(fkXFNDzkY4SSe3?5`h?~`2jCTnkUDQWrpEgdw(1u#5x}L1;M@KTD(pB=@BWX z&6N=q8>R%Zibb<txZOGb*muui0R9&_Idop63yz-Js50w2 zooa#WLbA|(?3QXF|GO>QcE@ce(9y?jm)k>*@2Kufr&n?2Cz096xn8W!&(^~4-q!7< zFcPFgGoie1HR9w#Fk3HRGjcsy^xyI?4c&f8)RS8ymMUJ7GXvdvwI9S`o*zD|s~=6~ z1?6Lhd;SGJ%*v!Ji>8*vf2BNPLky8~iLY#*UXGY)qCl#L<@T`|S(AV}0oxn+l(>#> zQ_+F2KmY9%ZqfN#Lk@@6kk|IsGi>+qe*AEh!P(`?8*akyA9!9g6afp)V0m5K6Yn|VUtEcQBb$=G$;w`%{S@qDvj-_gs0m?6lf`|U#|X=JW#Qt0Y7 zd~Lkv;?~aFBe26)KTO44%-d&LW=r+|i8|AUW7Q}M{}w`q3K^m@7EvOiLCIJtio*Xt z`+2{dkLNueL*3oO-fLa!SEy_L@Qi|4e&$r4hb5fFl-_%F>qKNs4M(HuU?kV70S2co zhipojPPr$PZtj?I=vL~6;!*A65H)YUGT?QH1f6%?0&6{y3}7A=2DOlSBGVDahiZgMRG8W&-OaXAeaUAt^Yq1?Vfa1@_$T^}6>(tP~gA zez)G7+}UnK&aBF~GXM%*S6g*n5^~~a)bbI}Ug8<8L$btoaF^Qq4jBR^C6(V2@WB`v zywwU)z#dgUr^<>5SRxC}7WjhCsUF4)Zr6a-2+eDq- zf{V0HYlO`%n1(}Ar4_t*%q?{qCRpFk&6CSSDZvbb`@#wh);kqu@P(7zWsb$qVx_Ns zol-f?F?zANCFI$%UvzfQW2Vb3maP%>Mn;M;tFgt_y&RC#d4FA$728fLjf*@e&efam zJ$9~T73aGS%|o5P0GU7Mfg)BQS?1x~W|e(TB$)TpsU2z~#RcSX7|s@PX-*ZhIU1J_ z*;4xuZBWn&({~XAx7~Lw+;X|Ba8vm`t(|&AY0Nd?N|9&N@1HYY8Cadfr`mliGVSjC zDZW-Om+pNCD^-}yh+F|IU_qDsJzqXfxg8n7g~3b!{;<?_x*JdPD$f~-g>7a8LL)uw96;{u?+HqIIGy4{tUWbQa8C4sTk{@u}-nSB#0=9Ho ziWbn0a^qsAi%TBC->GJMz1 zSJjjQt>)SUSA13 zr^jw6Wyi3vf4pj|ZD!Q3;fD77sjXi;V~n5$OyepvR4Yuk&|R#TIl8N7!hvyB?3|+CH}%|z-K%wEe&HNnxPM8& z)QDKy-mQ_T3(z-an1e*6m;Nzf-^oHKakn)@K_U-3CGuP5hw&ryyFG!C>;2rXF{SU@ z;X=y|v%(dBQiNu$$rZG*d*P)CvzXQ-=hCki=)>gw;>uU(p%UOood?iU zK)cGpkE{J3Pf9?Q=tBSip2A_b7LBcJ&^*H>2<8KG?F@59k>=Pll93YzO z!tm4!%k?34H2bZ2uclp__fqB89!+=S_p5WpDx1{^(yjaV#ZZ>&kJ*p)wce%w9c7T* zE{mko1IYjjCDe`O!H5^FxCM7_H2&_A-a@ry3*}#TIJ8Md!RG@RhsvE z=G}veA~N5U7ib?b7x^f^nSyEg>#LmqMr6AAEd26ESc9UwvFEn#Kv~w z-sj%8eghgLac{foZs3fZh13#bn4P2B{wZ9(1W0+6eRpkFvL~>}Js;;aV;)-L)%Kzw zczIHP4`vYhv+wNNYS3p(kncWzmaGX{JTvH1ddJ~g-FK@gczQ*?c?A^k_4c>7l%9i& z*Q*|*<7YXJ75Qy-^|8`9>irt~81a|G*v?+97|AL*R=|{vvslu5&Mq0Pq}I+ZC+k6G zxYVv^?XkKr&|Oqs9o{G1;y~4AB5N1Ve{>*y@GfrzEEo;P-)ZzLFP26PerAi#7pE29 z(WG|Bt=4ymCm|=ZmcR58=~-xIF7w8Y^`1V(`C>!E*6M~SV@O&A*=$c59~j)R?-+!0 zYiZF1eX>v?nh2MSBLbFf>vm<1)l7ir4{a+c%_I03MmgwS^vGG>hD@c#El6(3W**CM zer^KzEoFB|zlSZeciMa+Ndz${kPk#$^X>3l$#G{U_{6a8`vOSnHjD~SF21u9-!_Kx zr}^m$chXckg%X6i-0(x;{J5P=B3jcEuWwJotu$0O7`)`re;m{{RX5{eG5VUf{tm?+ z576#Zi_<|bl*BTRgW8s!f_eL{7zGXM$1Dkt>q4WrbrbET?d=-U$?n(Hqg1IhiR-*) zy%^PQpI?*qbkKKfJA<=^Key$3GusxLos1^xypphpM*n8mI*u0Cf4(EA^JgCS@QNkwMs~^~kr*eb4J;HoIDO`+yK{hzg*b zgopF~$Sy=@>z=1eU^hQa+v~zN>&w3p$#YCNh+4Pdr)&5vO=GfQroZ&t-@83InXDa% zC!OymtHG&*5(dan#?6lEAMWi+@^V-pAS#VHewf~y7@Wkb_3i8mX&=}9ptRF z_%h$fS=(rj&LQ4u3hTZv7vAfsoX<2%v@&&gm20RYB?LoiPrLnqpP7)g(RR#g3<_$r zE|{QO&OPkw)z+jr%lm{jrX!uDqLV{N8RJdmDd?cE-)N??Jnbcg4ar1d124DnKI=9-z{ z#oQ|%GFT(5ynz)Jubm59`%#@pO;}&Db*LNo+H3}clf8P~Y(trYJ2sudKx^hulPy;q zQ)6z*BE%W!lneIl){`nvcd-h4beYn5sa5|vhrtR?=2-+j?&0+BRGI%cc$~8( z$%YNqi+u6d`p`HHLB$E}p^pzk4%+v-axQhNkGj&tPguv?h1x`xMD`KV1eAh2S8!U5 z&j=~pE5QMJd~1aIX11=-Z0x;{2h%hlo`l?_SU)htg6Ajl@^&atS3(&U{lVb)Sd@0h z1q(FB<6Uli!)X~Pi&|?L%^eu_`08u-BzcpYx)*2BujER>Y#c&$bT$lM^$fECYDeW* zR?BK-p5giQ>!$Nhh8jU|5Lx0`HKCbcB>PX6v&7@-X|UUBrA*Z39Q_0?DpSy)Wp(&|I#)o_af1Dq5nN1bIWc z=dY~Pj|=VkZEvpMuCjTqYx^;Rrb^%GIfam;(mn%TlQJK+=XS{ycQCVeQhU}mK|jVV zw8z5yRt{J+$-cUFPbl2@?Wo$4s$^??O51>D`cAo}ziCyH+DKxbn?-vSYtj ziCx5z)AY(*roQ8Z0tn$|jMm|GEC_IbgGsgnJ6QPVP{`{ZvbW0%zL2(v;8Uc{(G_3g z{us=(GK#$ex3$>IhtL~ceoA$L(>b~DwbDO++ z<1CTu4xq~jnyYA8#p@c?BFdt=TTB2Mn8Ib#o}J`Z?gNC>_*z*!o@UYBtdtmP7FDI* znXz+nW*^LkxAUZVYHI%LOeB*Q{p@1znhrb?6C-sYe2ar~g8iV@2ikD`SzH?6JTq@2 zhVz%r{_=_g+Z+=iM*^J>1~a;5=nofMg5+-F=ehe2m(G`2-^CPMyG{CvIDHr8x$m5t zv%lYRxvqv?d=$Y%3CNoOW`0A@Wx&RG1yYXrhRD3>SssaifFJi-cKZU2%K~iEtSezX z?v$D@3f&>R&ucyyQ8+1BwVM3zeGKTk?4n3M9iAjNeMf^p>-z3I5@1Zwo*KalM***(I$agLJyCGq^H!Qv`AhqbjrIR--WPCcl(Sv> z{qO%5ot8?!{Ih^C>xk;B1DHq#FZ2n=%0Qp(v)lRfK2k5%??q4>>Mb;OuQLqxc-R^j z4t1btf+*_4#S@9;x&3x*y~HMaYkxYXP=;nWjIm~}NFU;~Vb`*o(tE`f-uCywlhAD7 z;3?Uz;meBw3>B&v(vJ@=sdatyw|3h}Hw;^Tc@de84{4m95f2)E7%tC>)$x<3fQhf!iP3!X5wn=d}H@kv_o~L3&_Kv zyS)i}8O-LxGthME!&o3+n7?TQfnF4UJL~bZp`sXCZ4exDuuK;S3f!|bKYOok{Kk=n zE^a2`-bJLf9-o16G2$a@e?_QGUH?41?2}i)$3iZT(owuD<|)@YPewna(RW7GD|n_i z`~G?0^}QpSfRB&itA%`i9vIJW)D>7LUZ0EEQD@mtrG~3u8)Q{R7U;t z>8wFB_Yi^6`{%CG0GtC zv~%wLya{fbt-pV&NjGA)jl)=40i*~LsE@C>W_^8+aVB%-w@LWccGN;f&#$~w2|!{r zGnQW)F@oVdY8eM?8;#?3)hf(@snXc(+uAEFxk4sdvJix`>E>KtdkkZ&#g(8z_?-~j zlh$kre<9Ad!LMB{hkN=1?(l*qDCg-C!$7Eq?Os;Cwp^gk!K@k?U`Rt7tX!z z%0q&wS;xqM&IsH$ReTqXsKi#y!VTU#zGCH}aB1sV1|n4O@<3Zm+UuxQW!F}|ea%$r z5WV+C5k`2l1~qD-lm*o%o`3T&JPWo7H4zf=k&HNNc;y4{wPCHal+F6}cgvOoC~6S9 zOuj;fyC!{WX6Dxk++Q4#hebF+GlqhUB_LO3Pt;4u{LIg$(Un0;{Co41KWzYHfrV&> z`LvAxK=W-Fw%GZswCq-ZlLaO!zRge*3z*YQn;orr$!*QF-5J zP6juY&UvkTl(Sh58|~G3v$Sa&-MQw=IG)PDxn*~UdajZ~mi7I?de9TTG9AO7f9v$z zt~?p8GOv|+TQ;k=Mv-r+LyHn7=^{Bx6usTf{|N9cdTQm0T`Pj^)@W>2&Z1z4`%37O zPP6fOdQCsm@nH7tkNWTFgRJcf@nB(<`2cF;O-R^b)x$b>pZrJ+;(gmGudGhvC6RE> za*&V8u+hI8!5K*C`24iCmiA)ZjZVq(6YM#eRB9t~ygW|6_AnPeVG}p;i1m3gm4~G> zWHlXy9y|T}l=@beU{h;GiH)vzpLIiq7tKti@o3>UP78KVd(44Meif8!-QTVP-ssB$ z7nLQRBcj~V(iVI=Kkd&)a?P<>x>LHq1uSMFrSa;WYu$_Mf`$abWeqhmnoXvu`y5nb zt_bDBRkYu8+jV1brVkaQw5icgUOJOKMeIzcpXKxjzA?2{d3>$4Q0Wzro5?v63C*N8TY$X6vkCAPM>&op&(HtO=ng;ZW6={& z`)y_A7I3pNTZWSpqsMF8ydOCUe)5BTRa4QQy^qP2Hmf`#YjO6_M?KA~dT4E4rKopZlG%DZRdmX!` z$69OK6AQUkxmxrd-=4fJ5r1#d%)yjmmIdg0_YP!oiAKu&GI)JWC40i{#wkN%_0B9X ztK|h<|2tVY)S!{ALp#FC63V{d*>F^;9X|SY$;pKyb6ca zb9`u3muS9YX(tltM6hQMK?gg z%w_gm3C?KRKybY+HvVNEC1eo!Gj${xZHT4>!&x`tfr#J)L9fJy9W2Tq0QZ5tC8jM6 zbz4hU-WGDFGU_$d=SROjx&)$u z0#nNhbg-&p7q#7-Z?&UNwId4oal!ERF$|`v>=)t8%8grMY2G@Efv>6ZTzQ#yX94}a zdxq4B)wG)DXOK~KFX>n~UXGS@FI&I+2B~=&^-yTdJJ}HCX1N+tnLfTGM}l*G z4s5!&^k5{{yAVHdD60shg-*k|l?DIr4Cxp>zk$x3S|MB9gLr_ryooWj3@wc~#k`Yp z_caHR#@aOfR6fGlV3D337fZPxZ!_zbPd4n)^8WnPL0NN!ekJp{#6k60?R~}d7Jt?B z2BgqY<>cHoHWW5kKZg$jB`uVzPi(3M;0xCyswrUEamg` zZdlg#^BWZx+if%vS_<<4X11%BrZNkG!Yz&%{RAcxqUroVOn3LKS9DIiJA#gtiGb3+ z+hf~;16GgiOK1x7gcXx)zME? z)?&!QnKv7~waubcHH9xc9{)`#bXn=PHH);4s6JC%7|DN^aO_oQMgkRpxO8C1R&C|k z0ZTWf^&AAbb4#B|l^?1v>w%><%cnLE0DM_PAE_QYjY_Xs(#;@NOS)-qFq53r5LnskvQ1%5Hkj187IKRZmc2%hK7|Y}~_x*A) z3n*o(6HG1h zCq2%1`EryJA+@*j*%`wYmviM~MbRi#5~hb;O+3B1eq%Q&&BufAp>W{)&ua8n6@s-w z9otR&dRd4M^i`z3%-5$5wDVUbhZ!c8FX=~URl}2h&mupKj^rIbL<2vFgyadfJ~gXB)$H)f8J$|~Q%LzyWwvu4g@n|Ebto<=$F0E1AMX!|aYC07zg za%gH+g?d)+8?NpKhYbT+4E6&^S_-CX)%=*ARsR07ILVbtNT#;6G_VFsji?cuMJ97c zU3Wf-icw=;G=&xez_$t#?4l8dSA|S^PuxRNApfcgAesOVeZ3#Z-anrTmhAn9n$!0876w!AVFfs<&S1l;@o%mKl5^KJAX+iZJ{-8{MMz zbhN{mkIO-YWX->Fu3Y<3Q~io$`v>fqaI$M&a9`=JGOHs!84rc#<0ur!xEOou)R)AiJjqeeuT=Mt zWjd~Vh3#f;WX;|X8f=&I)trDy6Wk>H`+BMh)f3$PaZ>1mmx%|wzFz6{VE!FSME1v>G;DU@ z6>PcAjeh%xDBXh`WHRc5nEGtKWxut#(>mV7Ta{WdI&?F?4S67`*rkjkwP%Ka=_&4V zR-w^t%;1a+9Nkh9)tZT<`#-Qv10rq)f3uDqan*C>Z0NWDNNnvoC!b>aFzuKx;Xv1y zDf3wP)G3aHmgtWCVul2{T*7STg_c4#qTR*yge`#6|K`QNj#X`=Ku_g5YSwC!q60=@ zgzB54&V5?i!Jj3DUzH7Vo*STx-5vW#HL8e=p>T0ktC!5ln3wuiwyg|$R}4Ac5Gnpn z-F%oWSmpZQ(HLp>WeRmmjviMuH?r;%P~gpA`m4-tQVYvVgLEytcdKplTK5;vPkHWF zq^RzpcgB#i9-0Pp=;L}b-}!O9`sPrdzqeRL_)1^iYYF%(pVjZkXlS)R4xB3^W*x$k zh+VSQ45@crh3>tWOfcwIi=ynwRdmTx+<1N;j*gf2Q?4{PK6|aKn^_jpj8yY-ND%VcptzT_#3R`f=7=_{t z0%gryW1{ndH7peQ;tT>+fN&N5s1^8jj_A~aXdWitUP3nk=B!TsuR8^^&*VEg!tU2i z9Xz|N0bbTQX?(s-*Wz|tM=k^bQ$2VGu6IYs9=}U6^T=Jlt?-g~gqk*}u8?f6x$ZOo z8HWn+mW9m92ew4R89A@6T+XUh%!zmur4OTY8hITk@Oy!U^j;_)c{|hgotj1`at*K5zT^3=gZ3^y8;Vf3+(y|Pjy}tC z2oE>XXM9B~ZX_O7+P#g$^s7rFk7$+6dF@}}_tnuze=qjT!=z(KT;n78wP_p{GD0CLK?N0&+7f(7b-b`^{LuK7w-7gjEfYTkv_gOg2KxoYE+Fv~}u)tTw#oq1^87=jE ztUw*6=QOj^@Z5U3fHq3v*UB>|b@FgUp4nV9!^01acb0x129D(1@*1Ge7O6nwwd&#I<9iTLeqz<=Pwy= z;8bWmKP&OOe)q4z1K}iLCv2xhkk)^@?F&)vAf&wzdmpjcKAm<9eReu8)CQ3|@2_lhfst2rfqx*vc4<~V2z_OtzDipi0px!+zA&e?E7A72H689}a%Ko6>*>5cC7EKw>k zH7vZ|$9}J3>%MRpv99+0)T&q0sn~&m<$gmZ52-MX0hhb=y6)ErCi)H_^!ZNXDTHmg zHh~M?g6SQf0J979O~GY;BQYcdVI2IH5$d%~MSMKz{NUqBH$D5l?*UFcsn-GR1G^`s z9*ibVO?uqS6? z1QbLY;0WmYOs~yVc6XKU&Ji%J_cP*ynuk1x`$x^318wMb&4UIKKydBJ*}SDxp&Vtq z1Mvj#X;IA|iXOGkDC^c89gX8H{q=Ow&e0f z>ffeQvFBX-(g&&htzrwdk)2nP+E-Jsxh`#((~NiE&DEbYQLW+R$Pxd zY#C(i@5!z`>|U}DcTVfRn_GE}6=dd| z!ouByka}V7&s@5yJPufIVu`9(TF<-XCupwhE!46h#%#BGuF<4*h&m6tRT_j6TnvM% zdE)iW#?E9YP8)r#V+N2Kbpd&;gc~(GZrNLT z57-KMx9eWC;-Gb!e@dYFyhAB3-9O&sf=LUg-q{Oua=YF@L$dP8U~+`7ncnNV{Dg zFxuc$?2jj%*>-Cmr;i_Wcp;G|xG1H@^9$i?mx&}STAhw&4@bk&W`1%ap<(tHZE;-; z&fx_YQn4PKNTrwbHGL3(N{a3cnAT89ME5x}A{DYSDEL(gZ>4`tdxUX5tzqT(bAcmzKfm zddr=2%1%|^7In(;tkllFW3ar1Et0#}%eN8i#v9l?y*8yYJhae&ttvCweNUXe;$Qbl z`>jm$lX-u0xB#`a{ zUeh*DDRQ-j4-aWbQ@B~D*$1C{!RnH;kNvq*pT=T|RfbdU=vhR=wt0EV%Vq;iq$EV>Ng-A^S-E2G2mL z68r1!CmO1ZC8XN7{r!eh8@Z3sPH_Hgb)gYbh4X&vG?`t{jZ8i!`8|}{=IA>}NDOn) z0L&Kk=S0T}-x)~YXMB|@OuL7bFg%r7O~haiSPK$_ujO;OVRiTBCjCGkB!LaFGaaDw zAc4p#Z!%FpX|D|+s3^a$mWqp`nITR!P}UARO3E>i{}2~q_d7Nxj=aO}vHdr^iYF;p zFW)B&_cDQZQX!!co}b2VRi5p)3BO{Vl(eQED^KV{1>f$ShV3sfRo=`v9s?AJXP&?` z>AqU}``sf8*28{XGFF}2iVX(;Y-h^naXMG}n>U*6VTWA2qRtbZIc%o0>vv~X>lL@V zyNOF05O^2~3h|DhE?F{Dd`sX=N!Hg@y$Xt7?($IAakbTdWz3^G9ZHq!H9!b`wCuzj zf+_Cqi@W>ulAa3+civsp5{pp>207yPc~+_iGPREuP^ohbQ05)v9@HDXKV|47 z+O;x%Y(hjGOFf+8EN>tXi;(A7PkGe~0C7_1=k0KC5^vXMhJ8%pVW-n(SBvW2D&{-2 z&b^!ByUz)4e5b*3(A{LU`>Ik?vH6xR@1@U%x%MOQCLD(5T&0{2U(FAWy&PKR0^?Y{ z&hCr;j}o=2`mD$E$;+R;WuhwYhBFrBVtksobxzxQm1soUEfYf_?P93OT?a7EZH64yO+N!^_y2*cZ9u9+odJn zC&ST?jFrrG;?c(5;z|qq!rj7LYqQR>oyMJJWn(*%Op32v&OVyIzMM_IPnGm_krkoG z$B5UB(bA{nbg`^F>O2JCQPyj^sg(UbG>NLnHr!jlg*scA5t~g8rTtNx`U~BJs}h?Qeyuq(bc~NFs@U5+CP}~S zbJVqQAAFO}0Rms9POx8>Ye`LsIt`lDLg%#Nq>GjcY0)u4Xv;=W)2AF=lk#CO;Bg7$!`y-55eCJNJLL&v8L2q}g z0^)?OOr&mUg+)_s*L$j=7~Jzq=lQ6f%i&y37rR+yQe7@rgKFV#ww#pK&V^Ma(p7w~ zI_mYCE@xXO$VPWDem?kVrKVck+62u4al9tB&q^W|MGeBGGL0#B@^T0vg%xR3C$yjj zbmO~k?i!UzMc6Fiu{dC_1_Bil6e+LsfkPw>Jly)@iqO&W*M28nJjB*(`mUzUXMPCI zat@Af%K|!CM4bW)-XkQ0fYI(G?>yLXWreHg&~1OTI3Nn8-K?1L(j-T((^;c7P<<#XqHq*o(u+u&$j|6QW=G^m{ zbC{U=>-D;$KpOORMeO0_xr|&|-g{#5viF4rbgWVdv^+!pZY{PidL;R#e5;?`Jy&1Z z;%0UDT~yjC+DfmVIX)AKE%RveyIz^D<+kOtIq_(D6J9? z?wii$!r#gk^!PSkFXnY*VX0COo%Waqv>$NIb@t1`;$5R0n2Rs7T|%7C$AvLy-Yc!G z*y$UmIw~)&`_dQPd_RZE5>BI(;Q_e`)t+jHz>j-llL{;b8jr%KL$yij%pO^pVSc z*H{%^BEss2H7Z=a^L+4KahM`$GT{I2 zK6AJVxnU8xOp^mWb-W)@w@5?ZzV&yt(iL)r$_yk$&DJq0UXIRmKX1JR4>VznU*2m53*7wm9)7P@^-?*x44bYTz>{49 zZK-+V_r(Pm*!TKOn>arZ?DKv&^UHRq?AGF$`rhyrPf0UaPeHgZ6-U=Za&DPLw)doN z-DeJiU?t>HgxdJ=o)oJGyh{(3waR<;F&}}^%5~<4J@=DZwUYN`s00$7ym9#R@qVxV zMDkeisl2G3Xro=`Kz92#hi?-tS8gR?Wk`BJfQKdIUoR_WV1MsliDz4e_A9 zP69-52i@m7)B4_tdfvEue$;%Kl)CihEwhsTR^xzl&mJeC1RKY4AVLVm?O5N!x7yGd zNa^fcOR20ujO3ReC+`{@`biX$j9dbrRLM7q*47@;>GwZnUXlzs9H4s7?UnoO3uR8-?lWSqd;oU( z80>~qD0tiFvgl6HHgCzVblx!PEDC(W9$-Ih%m5i*22^1H3m%N^i8P4 zO#4CWZHc9NOb!kG#+nJ63%z{9e+YtlK^-rCO?0yMo0Tmc zzoJ{cOcOcp4*8({?7=pZ6XPWHb*hzKO>^qIY;=l~^BHm1@gl3nVXvtwYp1^c$U z?qrwmFSrC9k<-u7Gd~iwJCao?`;;UbZC;IO+2JPv#W`vAM5{yNHpxI!arQ@Tiuff6 zg0QA(?bw=KM;`k?HfA0dl@1HfLV3n50IXb)pY4<_Q)73fdrb?d z)UNYXVVo&#Hk16K*pnyYPeX$P!8Z(M2Bb`!}ocpQ|CqDir-YGWvGRL-Fg#^br zSQN7kipa-oqklxI(&1H#koRwYJVOmq+9|v4FO#2j%HG}5f%j+{F<{P}`#Q=#&D9B% z;Pr2lD9vX*5=(^p5z_(@J9PTH4f85J%XX0Dg|WhN0X$VloRI98BDF!oOD;IIzAe^Bn{aYm z#?LI|rmiupr`YpVq%6!+nMjG^F?wuDRrn^S5>@kE}+!D|Bk_v@s` z^V-NMe@@}UjJzHf$IUdT*M?9+97BMc&9wZA2!4bJ93rD0*-kGN12Nh=+v;>X^rc&Q zyqz}r{bOsUWf&0`$8G-h3b511m0f`Q4a7mu zpq>Dz6a^v64IaIABV2dtPqDeAW#{gQeYwu(9^~{HS$5^>> zCF0=vz!X3CJnYEIDGC$+G*EK;g!W%15qC_AsA=-m8)C z`e{J;AkJD{uMUEDD_NWRB^6*s%yV3Y37p4!r=y-$o+#a9H0bVHOC5C$p(dsLHt8(U zaus0Oxg!eLJN^jThtDu_5UNf)i%TE;E;@Lt7Xt!=-a)VW#ZZ#@UH31}QFBf^ag0P0 zw?8&;HevDcx_g`Jp*Nx{O=RMBR|bw)#3N4!H)?XEj@@k;aRzh!!nyhh$zaWElRsJ+ zQBP92!NC>#>f=i$_&A1JjE}nLM3336#&M8Pe4XoW&VN7K_oMNV@^vN$%tx_P=VNMB zit<{fMN|ZwtNMD=Mi}C3kt@oRhx^2;JdfN%$~XAmjmO7OwI=INYqiIU_32q>%bqJ2 z&Uu%(((pBs%sN}^eQeU>si&Uq$znksly_r!;32qRj8E}l4xq*tsQE`p2Ue9kC3EKf z)Hy)5Eri;M8^hu@*%*Np`LN_GzCXz@fbfsWo^5V#&_O9|Ts6mcvlsA6=F7{|%T$xS z9DR$L7cfk9u)pjWmb z9M#UItpF|Wh0%D&+O3Y0P1pgB^?s+3Fu)dkJ~O3KU-10Z%6xUS*29*_g1s47onkvk zccovgL6!I$EQV3r%7u|<^cVg672QWr9d)xAg;|kIRlI&r+&LGv&)qR9t7rJZ`zH@U z>l2Nu*B1*kE6(W2h8Qiux%^O%8E#;-RyLkL{%}1CGaKcZJrtluH_J<5t9ok{y6@s* z@zK z_!FEDL7@y$#s)(JC6ys0L`6ax4Ey_^`~CB*v(~%Uw(&gO_wRRI)ZjZA!1Vv#xGZ7B z*;Hu2n(XH`Imp8$3#Nu5aan?q*Jk5p5Y{V?ZkvQw8c6+!c!!1P{87EWYI*Lf*T88soB~eDagj76&??JOUxPa4{>T<)R@w~r2b>G^f zxs#ZbUjXd(w{Rb`_C=qsh4)C{{EJvD8*>QUhfZZ^J-TKznoTEa4G_*0T5cDMG=6i4 zOL09^Lv7B^*xRRkyXES@4Ix=&Kw<1mz}BZAxaZ*=F7ENi?J1WZknBPV`VpCZVB8=K zs_7p+v%kF=Uit#=agIsQNI?f%rG-5g;5PquT|?Xf3(EZpDp+dO=qv$5f5qI#Z?Wo7 zB)?Ug$z3tlkA`{Z4=(*PPJ#yzeiz1L7t}L5OGBv{`LPep#Ovivl->8H1Dw?O%%b1Y zdTKgfcmz1qzm&7%&qrziK3Hy-2-(nejtIA(k|~Rwu1mum|H&&YUte2$pDAOFu?)Gs zYiepuapC=KhLVrh8olyJmHrBY4r}a7d+gNwbannjT2^?zOhifid#+p(c;m|VQJqc1 z=gNv&Z$PYEXZDw*O`adI~_WW zb^z=y`+=5GwVkYUvX6%I?`ZnL5yJp!F?VyC-el#kZ!FwF82C#|2E2Z!thgEuGib6= z)Qu7P%DFil+~sq7P|JDOS*;9hj@+Yv=^@YWU0VlAC2)rGN4&b{&!PQl%-VmKLDLRj zXFoW0x_{75du5vvKBKCYws`cGXpMhunwuxsIo_IB-)PrSK3bA>Ud!GaT$hQ4e~=*w zsSi#2&dTFngqqu%yIV7#LWx*Hm_iv}_w(}x=H#oViLHp1u8RxXehbTdZCbZsv)4w) zIMZ82 zh3{c~|9fti`N=<<2|LiN!Xj&L{t3dciF8ys{+esDx^E302Pu8}AyXY4PZVCG zXGTY(0=A{il9|(7JiVE}=ndGvYaMQVOo3fh;{IK!ao`1AKPcnR-+*lXEB5;BRivO< zB^b9V8DX*IG=JJb@p3>mk|jPR+slzYk^`s?y>4C+=oY}BKZ)&S1;py)HQml`>DlYO^u0q8IsfOu4s)xqX*n7SX&Z5M~tt3RXjK?@kQb$wRs zY{$!mLbVT0tJ0KxurWT85?gPRVYo$Waqqss*?e6g;LfivTX&XiO?>g7>l37m)(0=0 ze>!#K{ICyOvv7AG+S0y5^Bnz*`UYAK`NGl)08db+_S|u~;2$Q(_D;1a4tbm58blfp zn8BO}`=h%1Q}-;u-vziNMTs8-t^Q#9v?<6<@!*Qhuhj#1>Vw_L@{9O!mVU(oHZtzd z*xsRO&=S6P~aZuz!pBr9Z; z`|CVk`tF*mb-9_Y42FSA@9M=~GdY(FcKqT;<*ZZg4mOGY+lBMSWwo{WP1K@Sym$4c zU8N7-Fjp8|{F+sikx2>gN3(F#5)uuOU$2(98rTdlA|hKr&Q`hi5Q^ZVn9~F+&Dc1! zR#ZsTtBjDUe|lxna->)jNz*6+Iw z%5q^Ud>qx5F}Bl~Qjb7W{;y4;Pje_^_qtn|D?F7;i2L8V4+dN%?L{^R)|CR2uK2<1ZX9A{hN445qTqUh9 z3)q9r6S=i8!BwovIO(WQ)_WiM)uTk2P(Yto|F&Y%j{5!`%M!$RddVm(q;C(8&Rv;>NB%96tR9Xj!v{=ty|>b z6vMtq$2p@5EbP4B-KJk#!6U&WJ@GaY=3Mhn@tX;nCnM5hx}!m{Nsk2h20XwEY~`5{()7! zHFoUh?^ByTORz~S*QU83UAFI=xKSM}=5@7xt)7hVw%H+j);oOaMze!Wt0*ev4rtfb zNK=C$sn!tIf3O0W584H*)8q=%2s90U^Z0g8#<$Jw{QPXJKj&5Q)d1%FwROk)vE07C z(4>^(R(9M-79@uRW{!_|80IpiQvGLSf2%8*yNBrHA)ClDtglJQEXXzWn#V_2?Cvs2V8{eb5m~3H>+}DuXyACpbZXPy7n4=oB0*f2iw$&y8o4&r7;i> zH>V?h=G}RsB z=;qxDNBLGMZ1X|cE2x+JKHEPG@Tzy7%OWC^4S36@M|F^DX0!Q2QaCFwN}1jpH1~ei z^Ud`@-rOr!`8C`%+5|jIKfUL%c^x0O$<@o5MDw;w5R$2^FU#LyUWE86))5w+e|d!* zIhf6d)kksE?@TA1xzIXNWQ7>d-wXIu4u_laryKzg$)oFs%7yK*ntwquo>}79F^ttG z_yVC8)VcSuqukfLb(#(eDej%et(A3l&}1L)!=()w zSO3%e+^p%26C99W?$s|b3D!va8miOi2ER)LEHwD;{$~IgreJ;r^cZ0wp2(dixYA_;*YQ9pB|9vY)~rKth&GHO0GKm z?X@{yUR;HKRPAGv(RY|yjqlYtr1Sm^6C1R?IQ3~f`@ELH#6Mce#=t_@i|rGBbJ~yZ zmp`mQT;A`lavewpf~d+{ct>%!3>3>EnFCsir=c2F1Q#CrZQ)5B}C4g#Ya*~5t4 z&VBLCt4^X@3&+YlKuTQ1VuJ`8CTrO~9CDPoONe7~X#I(_7VHU)lQJj?KeQ zJ$a_M%ZSckIrIE}%;{|| zT4G_c>;kTMT(*$hrh?XkOA!Ab3VBx zq%#EPOF*q_E|CpSuk3c_5&HDqWrqp|WP3w;@x}EBLf-w~NLOyOb>aa1zUe*p{%1_^ z%x|{D!N9&5m7-S>Bl^}W#477s(r<3&Q_k}MD#KmFq9sfL0ls5y+>+zVBSpzyf_4Yo zXZ0PsnYOB*^wKE{*W%j}vQyUOhxjn%8;$%doQ#p&C%^cYQ<`m`EyuQ3F1LI9YU9rO zW4pGyNF3XE~kh2y!!Btj`rH*=6l7e?b{!+3OCJ>R`TSR zc`D>j2P-)4rQ@RuN|pTtcH-T{hMfM>uUOT^vc*>L$eWxywQkBspnM|;y$645wV2| z_C4nnqVSr{wPhj(62l@sq%xKZ7^a^j!>`ZkcZ6D39vnTurHACw2HkB1f{@PU{cukr#%7}FS!k^?I(xY zgGhIi-SU`0E0Kp76e*;daR6Xg)B%fM(>m9`%htTAs3*H%6lcy^}qh_()y$V zNmKik{9LlN#gJg~+je(mkvsRcuz_8WlJa-KJn!ifm?c$svXIQ`0X(q%G4KX8zR!;H zc{SM1QzF+;Al9T9v4_&2ZLQ@NIh(|9#$}ip=CMw>+tfeC?P+5a*IJX0uq5?OF`j5Z z%pA+&wciroHzQ@LZ=whe*Wsc+Y%&}^y4*JZvFhO_r98x zyRaf}qhBsxSdyojJKwseYHGND$@_*k3*}bc`fM^F6jv5GLEd!Hi_y$3+W=;LnxyK> zAZU#~-Cw_3x+TqflacoUaFMK#J!k86ZetA|fpnCkajNY5*KTr*d)`B;mj+9{(%&Vm z?uJ?(`PB~!Po0t)BNDZZg7%Cos(zt}!uMG3`B{;>N4rtGHOQ>2U;Zk)8%O3az1cJtC1(~Sr;0=X!#k_FtZk#QAPO*l*6ijAQ4qe}SBRGKcy z)EZk0@?+OW^Z7(T6;+Q4hFVv*<7aN!$9+1B!?n?M_+y3nJD@FVHLu_Cn1kW{pkQ)DT7@nWTWY`3CM zWxZ(S1i#RxU$xbnOJSEZDlNzRE1njZe}AfaxSGy;x39~&g)$EJX0e-KG-!mklGq)O zec3AU$J6ZD798PaPWzuF>t_Pu{SlnGxh_AO_g4yiTs>^*vus@V^^ z+2Zo}jP94QH@cK^ydw*lZlLF%*JuwS18zz?Mb7FA?wkyr!lyb~9Sgb2c%5C;3;3FV zB+ZnD65|+hkj|xwcRO_OCj@nvcBc@BaR9MY3sOGXs8s7(;e^?Q#b9lz&(e4t`oWir zE$phoPf?U8Fz`lY-dLV5V68bN_J&1DKp)!Z3uN0Hwl-U4xaxbi+Ody+NskJY`tqC_ z=jUnl8ZjS3Zj>#NRNWRIH2v8G`MU{?ZsSm+K^S~r%HyvK8>@|bHR1-DFOp{;IF-pz z$_Q{~&C$qAYL$1EPWlnKIVw{5ukJ}nMVD4Bs{1N}5#ToLVfPR@uW#~fx43|!Eid=0 z@R@o?pc@5z8I(wOf|~p1O;CE+11M03J90(By&0SctcQmaM6;l+V(y&RQ}?yw!AyzA zu0X5+hf_G-F>zDxW?a9xN&(&^-Pt4Zil~`5%>w63*sH3ss8hJ@TqR`iFVVdpeXjQJ z*s>>$K39D={T{x_!1iK1FpILkhoPpX1H;U(%4}p&FftlIJLX+27xK!nu>m1Kyj}Nt z!pa&dIMSC-t3mpw4WHC{(LZlKooG-6J`6PBO1a+ZSi-~EX90vkt(Tq3cg(r4$7Q(ZEO{L=LtGv{Q8Ig8r(WIK41(Sjl8<>eoXvNQmcYFF7y5oE z=wWUJ>5h#Y85KzDUGGcqqhR+Au}s?9c=9aH=OgCoj+ap#H#+sPxg~vfH6Yjla#;tt zMCH4DslL)>ZXvJkao`@86oD7)9&Q5yeGfO~w!)KJM1gj#l&p*8kv#+*gIehCZ{{{P z748mu>3g}4oBRM;_srIO={>xj^>?>B{X6Jib0Ajaob-??3)ZhyA+kKms_ZV42XXT#>@bmC4|H8SeM;pY#xf|gN}BRNKrT*?{?p-x_ba;SMaq@;_ru1PAt9c3MBF^ ze2*goIK@t5SAPsh1?DwqXH&-yQ2gdbE2`%okM$b#$kN?tKdPqsF}dg8mqz;xFMLW3 zu6ces9njsghfZ7lPp3OR;g7>+r#0%st4!gWQyE=hD^~YyIK^z5gBX+5#;dc>OUOe3 zFL0T~eBuS2Ey9Odo}b(of9>l&_JC#GYf2wY#*Yo}Vy)W%9=-KI-?JowMQrc)L2jyx zxt=~9_X?HU>Gyh%R*|=cdvfkEE{A5(HkciSmubrU*-Pr%5!ij>R(OV0bz4RY`*6@` z^@^*vC(beVGoNS|=blbpP5f6&Cz~p=c5G||`kXAmg*2_Q(Z*V-_x>@{U!N-M#0&d& zVZ5}g&F5P*Z8zv;{M#8Ckhppq^ocLd4+tV&s~*Mk?ZTx{^dRWzG+()f&*Km!i#k&K zEjRmB@7c?G9p)83Q=Wzd;o;Vur;@NO{@HL=3IWHTio+xH`4{fq&1s}Pm@~B5^32y! zLx46sYfw1_FX{W93*;D?;V6@;k_kZrRPk+=Rm+BD2(|m$btVY&K<2&Y(~7p0l?Ux) z?_NbqFt;qa^Eq!0OVGW6$X*T0tu6BqnB9GolgEE>>pOFH^%%nD7823UZ2XVUXV}d zA)@r2OVlAMZpkfqi#kg~s{y9n1aG>=n4{^Pen%A#Wtph1F~i?Jd|@iALGwnyFgq0w0JYH57S7X-s@*69a@St=Y3fCozk@vz|n?6SpqfIZ?iIni~di|7g-g;Oz z^Xp!2QaKJBz1`ma)#>ugqIYNg)?|tOlvaRuaU>L0 z;?rMnd0$9~u1?O6Q!#ff;7RJ2=%e5HoLknM%%+2Q)Td^=ZT;qpHnO^5d@uJVxAYnI zItOf%+oiC36{A)0>piFL(^*l|AM~7`&Cg;1uG;D{&9h9fS??h4w0!hRf5Un>(;DgG z-emW?n7O~FT)X`K4CX8nsGCpjn<>1O7os{3pF-;V4d!0?{CtTi$QA+%U*~Hdh^6a)1`wF9Rta zeh2TgSsQzGqYVP(1}1oHQkE*lppi7kUz`%og+ds|KqGnF<4vAbilO-h&g246wp zpcp#4Qqrn?chW56*_r?N?jUd4eiS#WG9-pBog-Qyep#Wr#zr*2Ch*2Hd5xnLGJ{v_ z_D*A9_q`$M+kL%8u>HYG9j%~^)_~&18XKx`5|+7R4djbtfDyU;a4z>|x7Mp}qV18h z^B+?9DIBqK#d_`58RgIJt;?aJ0HH;#6v|XRKZQ>vRM`x$%yXcFoaYvZJzJ`?ytZ%H z8zPq>(eO7n2l7FEIJd?1b#L?--YXhs0B!oxD3R=jVoy6RX#cK(Ch3*hLHPLFxeeZ0mP#&6e_RJpIiX zE0lELMUbk)XdFs*ML$MY8Qm@G36Q>!0gjO>1ue=$GA6 z;y|Bb8!n9q&i#D~wIe?53h9h%!MfTAW|((uH{Z(M}w^1?gl2khMsuixI*Nj@@=9|zIc|s;GV}K^)&V^2?}q?z1?r< zr5C(NfyIR|>bDlxfwNmRXiA+~)m_uk52t4-nAIamSb48~G*Pm_Qu|fXxkGOg@wmwu zd!pMmkm>wRcjTcZGytBye%r^pJdUrKJ;C3w6aPRhJ~vH zzpJirX~YDOg|qhM@wHzL|4=j-yw&BVlaGzDHU8amgTm$a8HIv1H$lr5B-N8 zJL`snY+Z6`xBhbJ6ik8BzXTb!d&+X{B+~`JK+CHPZ{t_)$~m8Uz+w!*fq|B>B%r?9 ziR^l3=YI=%(VIJFQrvtHuAoEOmaL`WX|To zjoJD;G5g^I(t|6c`~GCT#+#d9vvwOld{*CEEtbl~a~>grO6_U-OGxeadILC^-K_P_ zz3k%?@GbU(m|hM|SnNGIg4cSjOjtSp-9YT~E~r-i60b40UYRC8=p$o_{oL;P_5s*r z;8R8}c_sxzopZQ1j>?P=#RV*2{Ch;~o#PA)dPTd=)XR&>ql|cv%PpOj?^|~kPe5aL zLk5dlVz(4yrY>h})@+tjVJn_*kRDVocrqI*G5BjoOLL@0d=W8kZR*VS>@~J=b=lV6 zJEvPJI{9OgP&zVJ@YV|urlhTf^oJH$vRiv8LB)Cis^c}__t||OfomiI3D^)`C}<7z zk^7ovDq=gZ#@MUT0yP-A2`hug(jP({t`+mUpz#HL*6Iw-N_m2QxqkrW3+(#KuhBhu z+01Y`C};epxahBH;a1y1+^5siAo;nls=|J^h1P)GnoqhY%~K_*LU#y7uQflHhLAMm z)Ap>4Vw7pFy1UMJb>1e=PWjaSPOjb6W$V43Z*;;M$9(>;uZK$aSvpfRQD3B+--x#F z(DNG;J+D`owcs{Rd|mCk9qN~}`HETinp`&?_{DlI;DD8v0E3211QQUQ{kGBlYl+=K zA3;l!(qT3|Z}Mng_PtqP6zTagjIWPqlD4tDhqgnvZ??e)xO@$t9Ha;FfPtVn{wW@B z2R|1efs%au{Vk)3tcHjWWGoJQIrqU^E`b}f3Tvjlxx;8y9uS1;3|(~(qY7a8*rkZS z;ijiXLa$tjXfscGjp5yg?Zx^G2~|#-eU6CA8cL8CL zo~S~ptvTdkpB0hZi8)HFVblvEwE%4v4+!H`>(TKsLWW)~XzDQOfrSqY!u1W`ZbC|} zS6Zf>-KXIt%*(IeH2AxD^4*IEzz=E4Fv(%*2q`+YF^#sh5&J3K`w3BxGjgB&rpHj4 zG z+p0B7R%M=3MzG6|7kf?Oa{?Q!?%NDGUp86W%UR)2JG!Hlz2o1d`}a0oXzj+TwjOOG zKdpkX`&BqG@J{XmsIOW`q3LQ=bD2M#jOquxTcWI8p_7KlqK?$e+2lf;mA_5D;a)i1 zD^6kn!@m*z$kFq^vGCqDVn$l>lao6<^R9C#BH^Z457GNpHtS6Rp2glc+HH6%y$>EA zv%D~c-%kV2&*}E$*=GV_Y41b5gt?9Um3-_VK7MH+R)*L;`?TNV>YFUicL@N)K2-r& zi=+6)c4j11uSy8B+O|ba>ODBP^SiC#V!u?kIn-7AiD!O(HcZ$m-d*|h){oWGJ z%Gmo&y=!EmQ{nwBlU0d`@(S@Wq?!0N4z}^(Migna7zWSd&^5(A@l#oq>p}_?P2;y} zQ|`)SW@WVL4<_POx=s1Of_rLA@q#(`n627_TVL(=`bc4nr3>N@6tv4GR(Wvq{n7hHW6!&03#a+h5X!DAG(=?q2x^^YRd9~@zoW{eu zUnUx=!~)#LcgiFC1mnvh$6k8BI6-}~Tk-f)$L%$$hSPnO&g0Rc3@+Kj-`~DiketkbMs(ZPjvQfa+u6e?ECkL1OVv!zvT<=W4pm(#1%ev&>l)3 zS?nn13k^KrCdzx>5P8Xb;Kny$eys*Vq4as~U$3;iOF$%H<@JgUoiYQuD2RQ+Heh~N zTVgAC9t126A$FgUXx>n_a3U9;y4C$cR|33nyxBaZE9=!(cBRo22D)0c<)w1}q4Qz6 z6g_KlyHrvwayc({UeyY|6z1=6Gs`pLQqMyE(B>BE=DYIMV(LUBcRkQvzj4UJzOwTp zKqj~`Uxq#IiBq<=KZzNg=4;0od*-cUkX)!$*cd2!A6W`I)w_0cD$~JhA6h9)eib>N zA1(E;B%RHbU+^@$+~AU|s-0W$Q`fzU|2JJj8fvop)Fw_Dn7bl>o5`r?oW{@hZt2xSV7o!BVPN$Z2(?d$}Q8b*Xug>d^%rwt?`8HwyS%|Y>&%z|2}GLItt@# zzm?On^nsB6?I4S3-R}b7$MoS2vkxzFuPJzgoe*W%r+>N%kAX?OzYX(p%o8JRI%MXJ z`(0(7;qShjtxYZZo$!j^@P_yOHQTb;zWt8| ztO0<4wu{ssKM1+;|774@%ePHhE9YL0!gI=f&>^`o#$~=fY`y%$=+I z0@=+(-KhRW@QN*LV2CVR((Vo#z1W`BmBFcL6UBhzCed8jnUm+W2Zi89M_EpvF9{Sw z^)3F_Yvg<9<{vg+XxCc1Lk0DH>5Z}-YHsl&T2}AhAy;fviAmBmVUt)|iFINU%T^A$ zOrMjCH*|K_gc!tTuQwJ{lHX#UmOGa)gt^}`^MVq7zP}eo?jNS}Lw9>>%qavJIBEn_ z3;)h?;m(8iKY?Z4qq)jGtujpPEL>g+_{jH0e-SELr7k07A9g3$rLCn(`1aE* z)fL`QGv`sqWDB6rCcl*zgOYG1%>e z#oy)g1qEvtb{1C9pHR7uQ#$1AGB$kvHF`$2fQO)S-Ms@oB2m(+PyF0y#ar*DpC+HTLfMFHpomSXtd{M%w_AD-bC#YWM{X_N|oV1u*0h&1^M{*$_wkUnw3TNec4RTL?A{qPosz-4R#0=_k`~qWY z>Aaa%neQh=u%}Oq1^)b03)OQZ8Pdl*&KiHhdAGPvFMQdQgxrw4PZB5cMsq-oXv}ah zS~I!UV_1id2<-Pgl6?=fap8V^*z4G91xi|L4?1b@@s3Xdg6Wu;EWW!#mb}`;2rox| zgDwqI5Kv3#)vce`oqBjh-J|F`iyBD#b}g!Kyn^y>Q7Rn@-tsWz;TtA@7igwe;(|f$ z#Vz%Lk~fO63mea?bQX-fJNEQyu@}8Q)@fA}6GwT091OVvj~ji}72xitr_ms$-WY4j3QTXWHu7?H)F&RW0?O(1^|H2Fw_QJ?>sMbS zpke?I=UffI!7#y}XMhRFzV3(p3=7fD=Sl~%3Qw=`CJT3?1&nTxf+p_RDl+qqsiSIk z(3myn$M3wx>Zk><<(##wU*Fio2 zB;SfcydcN}H&~I<7jHUg^2nL1UUA0qKT`j8ikE<8;>rFV=$c9vKp&zH*BuD1D;GcC z81Q3yLuKO@mui=?1M--(we_M>^}Nu^-Sa|uu$z{D!8v-%mzS{Ng}BJ(o4=E_jg8&r zSJ8Fkv%fA@peS(p<+>5QSWG?y?<9)`HdD791lh{dtkOK7mGQ|pHravGQ;(LG&Zy~z zS)sz$SITR@p62-Hf2Ww&8p0Kmn zE()Djk7+$O6{kj+qs8_)6r99|_x0wKaMu@c=GxpLs_mNA3p|k`U*~hgoTyBG1Z2@( z4AWT|H98hZCzQajJ~^DMWu@hiPt&;`He1_&F*kX&)2q;shO;b&RSz^x{~#=4=p*1ZrM!PcHs@1vIM=|h z1f)gyFvrtDEnS`0=CR!y?Y@c$pBLsSknLA4e-DkQuCK4VwqH0zms!j+2Y)+VV!=wH zctDyF5J1Ym?Q(jL-0i6W!vU&T)*?vO8AxD2TZl%=P0C->s{|_Y4w6Un=$@!q%&jOoWB7%IcjK0@W z0#%xg(YApwgh6W?>Ux9wdNUZ$m6d(-Mt;;B07diA)X{f1Aw(-Tu>TH=%d*&%lQIc= z`10ixpMt$Io>TOi(YyDx0lc8(G~CgZ_Ko6ti?Y!ED1GA$Z1T1LxEdiUpRnSly)^tP zeun{$~yu1yMz;nJ=9wDrLG z!k?&D&IP>M?G&@_{82a1!Qo?JHh?+L6Zm~@LkM!QD4M_ax#D7)!so>+Zyy%KpC3xl z%$tUMe77ELskjFowhaE&fG?>6s~fSuz9>-H@?*Drk6xv+h^ zev;3SOLIq({*dd#y*g{9WEw+FI$G!rYA)(!vw=YwhOapIVec;Qyz5V+6l!E2hLgD7 zAF$+~&3}e{*jI)Fd--tm#meGyllp5qV)U^(vjTtp2qz^z3*|$FX6&4*Ocz&{Z zgTGpQfT69?Y=U;-}up*9Sb!!vFYMH&%+%iL|CtMZx47f&fyS#SDC+@0d}Cq z(HcCv2-F;ILyj%9a^unvtKz7=4xv48N=uVBSw_|>Ro2#VMOfd16(5649YSp(b_5FQhL3LnVhN}F_t7akf9=QX3$q>CJ55IIB0}lcNTJj>%B_%Tbyh60 z2oyNwLwaC~BMqJsuy3s$`$`>}^^;ov5ijdoCK~0dRJq&uO%j{0=$+CUs02?owFj^C zR#&45`$d~cI{e$@20{niR=?uEhx=#?vW$59!_>*+_x zT8qR|S!SXOHTEAdCtVxEt+4<1EOwGS-^Z1H3}=lLQ}x^7%m;p0R ze14$LE&<{p%*M}kddGy8>S6bqF{U4M_kILj<=LUItR3bl@_q?E{)0tk>)o>&H=6pz zde^)yyQFxS=s@FQ8fVA&Sw;RD){)#3=63np377KbUd9(OM8guukGWZy68B9ux|Efl zur8zd{E8}Xg-o6V%G zo8U^GqiiKSEq82Z_v;OyJJf5zXTLs2>V&K2x&vw79W*?wJ<4Oj7ld_G0tNGWQuCTu zE*~}?a4HNB55o@F0tJFHIyc*fJ^$RztJ2v-Db=&vL$(repG(6Wp+&TLf zf3a&zD6M9x@a`ds)x+%3#UHIN^aD>dE9!tCIbHEo%Tmzx?%P;2LCM?MGHj(~cSCwt@dUEk9ANgN+;hZ?sT z6k)wL9G<(tg!5S>F|VaN3K*fdR~uIIuQoNF?3U2-_UVwDq$vw`%M>x=EJypg;Uuv9V{Q`lEF^{}@7BcjRW-!jLId2Z8{g#EaRc~q@sJ%WOE7XT#8!FN(THCizTaGC#%#6fDSUuxw{(A###uf+^MxH6!;^Sr zHvtsp<*LQW(aD0&`L)d@G;#DnxL4)+;N*e%)Hk(=-{X09fB`5<2>|jQW~5)Vyx0B% z-{3k<*4l#wokAzSKcwr{9OMq{0U@({&ku+>oG-e5K;@vD15vy&`s*XT6WvvH-2W$l zTG&Xf*mb)gZ1leUe+$_r-b)cddJ6B#j^3T9xpC*3Pc`ovx#~=Vrs`I06sO^a#0Rov zJ-~qmvtKwXe```#~iBpy#k71 zZl*5WuNp1{34s^$~q6Rpm&;ACV`b~aKgsts}gN7UgvuBbo zHwVGW|H^q0Zhiz=(tSBO+x>5oXWFNBVMCDVs8;_ZN3B~qj2Y?jdpzqhaP0f@pPd}n z`x&=7D@qCec)3DAEwUPn2(U-8iQzn$UHy@l2r_o)pCqZ9?{f$L)Vo1uacTPYeJi~D z-koRGFx<@X?VE=LPVNi@oi3$CCHRP`etya``o0`LOt?~XTMrr^-Yr-^M2p$s-2YD5 ztC?<3M=c+v=Lz^%eU`>&ERTAfs1DW9#nP?o_#}K(nRL>CzQW`A?;Sh9J0_fhpxXZ2 zcFuWY1*raRI*sY>znf*U8*8C4=lNBO#X!aZPq(X}55s1>4v?om0@Cs?)R5geoCnvU zt(@VpSkT=e$U&QE&ak%g3%;HWclG^)VAw%8Q}@{Rb+$`a#(L6S%8_3?4K{8L^=jz! zapO^~9oQjw4AztR8}*cwh70GF&wIM{;qILdquv`At^97hr0_Sz+b(h&(jzCjFQax{3V;x?yWH1c zR>ZFd@s&WuP24K67*$#Yd_5SG|jE4CfpI()qp*f8}6gb+t;wmWto7A<*? zbpPVGO{EG{fEr&1Mwb^{+FINSm(k?*8I*~=`f&$ad4_F4uvoPk4?EYtf+Uzr_~8Nf;m@i?TuSx8=pjW zqivYny_PCD=B6;M)2R^zds`~1>-Q-hu6ttE1C`p)x&boTCXw;5E6)1=KBoZsb9GR; z*K=@Vq}KqHK82;<-wV9z;8NNw3#(>aFNL1_M8m;x^oE{R?GC`PQ>(tXG5BBvF4f<| z49gKRnB$qiQv#3FcYNsoE$M!DG_c8Kt=|>4)5YWBkJer;s#h1*D*O90|I7|L7E*`V z+yrYWPW9$bD?V~Tr(qlJHCQYjr-s`bO_SmsiHYTj&hoEOyYKgV;Fsi5`D=Z16E9f9 zw(sR&p-Ueh+6F0%RxjsH8^Hg~;Y!OL$@Ls^$H`>RT*&7|qYMZG#7F1E%%7i4uhKMA zq0#gt!Mlv!-Sc5y3vCV?8(FsZGf-pm3z< zw@#fI^c|#1q$V7Ixl^rtO z9^f3(O@TV8V#{vDW~S5ABK##(zv;{P$Ubp2tQP=VC&i3;EZr(DmHy(^ZHpC*&Ibrh z=<+C1NeMk=U-Ru(D_s6oj{q*vmGHlRZ^`;fJh@{Mm>FN`5h|tSr*rsX@HOe~FEhB? zquzbJEbye(`o)e7o>FVi@E7p{aIiE6JYJcFyV?m2K{Ybf=x2YffCY|0O-E&S5A8!m%6o; z!MUDE%O&A{vGYs*hUBExqTCvpe|wwADETmUKfk1W4VL15I7JL_ZX>$q3A?b&^adx} zrgVP`2?Etyt*%rnICJT=oP$c3HGoaQ`eJ~6a4W#>=H%4GAGCxv(ek47x>d#HqROiyZFya8Mp}3-g`2_4oFTzD zZG2cAGEXopV9F%KgbD&z`u!VJdt;cKe|zxsnMQ%|PUX~rG0Odi{r@*DvcLNJ8XGAN z05iPRiUFp*!HTy!IG4x7;)20FP9OK{$cFT2pWAv*JaU-)Eo^4_U*M8j{(!P%>(yD! zK;;JgN}#}PsMWkHfEjvhZ4xy(POCbBj(hB+X0J)E|Gv_LLu3758k-xy&?hV$bkpiE zEb!m*vj}k<8qeqpyAaA`5fIu-li0%Xi;(+Dn2X(K+=nV0CNdIKQ?J`*mx)f6b*3s3&ex6x2OH98Bs~SVlLXI2A>#v2KIugHCbj-_|7$! zUI58E#s^R#*dH3_S3iX<1&&- zVCb{p_|lvbJF%S64@p_?%Qf|3PxT+cbG3V}N>Ed(O>*UM_|%na^kF}HrckU&DRmpX zAXEJQz1m2wFTHtjVEdi(@2cka?l=FeCG%Ou?)mGCOsm;*8sy2gEA*oJ z6xK`o7;dIXUKVy+x9}6p^Xqu~O!caeTuWNBV{MG7@v}be8)~|@QM|q?uYus-MJ|ki zb?>V2_FUUy;kVJ9=0%IlBHT(!>jN=(eSmc8KAkOetdjXW*EkT#uL(b$4dF$bd+p@} zz$JDe*Il_|^GXtjQ!K2jZdf_Katy2gO|R7aa^HFeu6`tHYWcQV+OW5lRo|5h$)Hj6 zz9IQ9`2a57o&ddNZ@ap0W=D-awPwhyEyqvPUQ8KjFiJRF@nXWveJtFw&D9R zrqnv)fxLa@&E%~$iTtW-Cv)HWp_G^QM#F<7R9e*WONYmMCIlLD)S;%N@@Qct@7+gb z?e*$&O8FiG$9HU1EqAWt-qr>%!CT#8=jHajdHi+Fm|dGcAm7yWhQNdyBc11*zj+?m zG|EXG0?Y{12N@a8~AK%tt<4Qi6=^z58u@g5M1A4y!UHzh^T$kFhon{3-f zCvRGLje<@bm=aoOvZBb)sEqi5%pje5qc3ju#bK;qm3zNS?L@Au^uCYO+g}&QEq;SK zjB$DHeF-SPW3n0q9 zw@h&`k!p*exh93HU1US94Q$`e`@#$1T`S%Dg^=52{J7KL`R8U>@=~7C5E3tL%bEDM ziPzxr`j$Zt4;f$U=pP@;u)}~k^=PSe@H2IQeQfwAdaTQ~ukw1wBI_A;_`Ow;o_Vut z%9DNO;g*_thEL zHfrlAHe2&RlJJ@jWjmE&3RMYd&;%jo7a|(8uhAduwViY33~%exP@jRPa}iuy+x4Ew zo-V0HUPWgKHsMXGTLDo4r>QfD`FF~@LFa4F+blJ_)$;x8h27a@|2woV=5evgEnvj= zbQZ9tFZFK_DdzC|k2X{?c}j1$@FtP|WbE6;0$O_LXSII^Gx`BrIqu4@(%M5&i4vN? zwQjW@?+Bv$QoKgrhn+1WyV%E=;sV@((tO7#`>6>~Y=tSjGvb)b7fxik$R0rWekYN= zF#B2IOl@{U4g&$0|qv@?crf0RJb*`0S<$CehV43?a3H;^OtSMl$Vc zViSz)XWMcVyqW5Kwac5l0JQ{46|}rU8nc7FtPVdC=2!s=O$q z^F)Kz&~kaCG=co(92#xs(t7t2YZi?o4d13yGG4EfSD*RId^UGu;_l`Q6zJ(6Q!U;6 z^WKj;3}0A(rwQLRxgO2$J>KQ9cOplKK?OVh8R>kI?2Ztd~}>H*l)`Gro8{ zYe~K{!EbO?n_MWC{+Q*MeD7Pidd6doILIq;sTIMWH$9d|hobz%g5=oWZ`>UHWq3(> z@DkB@?U+O$tdY_ON<|V>2Oo$nO9JvHgu#98w!-?6#I-V~G0fzTCKt#`s>BZ68;<|X zfG|s|ioal`;%&%=)m^j;yn`E54$yJB3Xx6j7{Z>18|6D*ZkY2cTMf|DZFFy0Zxynn zRjciK>`VP|rTQGLipi+9#QAHASIa^#g(_e`0)u%fNz=cf=-`EjJDbup1ysPoQ)Ya> zQ;U1uN>{}%%jWNx4r=taz!V3aM)KYpTQbZgpoQzW0)HQ~-t(6zsnhM8uV=2_gq-Z} z^h?r2`Ya~9DA-nbcN1;WL^u8#;q#?W=Olmc}%`>?5+;JoV?5d-)^SjXd#K?wSOY zalW9iR&h^xi1#=67+z;Z?3u4ZP(Ad^Q|d+wBn;`(zhAYYoMtF=tCfeeZu1Dy_$>2T zO(*w9Zz#4Fa(!DP*XCL-j$9yd)eL-bT-_7Ey`$k7V%TnnJ-bk^IjpB-sLBc|AirC0 zCR*DX;2jP*u=c%9Ctg+TyAP;ZTOL?o%P>U1y+6QqZ4YYAr;lG+Mdyz0W{}R%(YDsO z48{mp*Zv)6UuxmsVuSCUbwbST zt-ru?u(`3r?us)RQTBJvPKOI3CSBKjuiHUQfevqdKNK`0^AdHGiPu)r+I1=seP0f zZBWvkKlnv7&aZZ2vx^LIQ$8-J**z$>amMYK`1MFUz>*wSsZJLXM!$KRCJZ7P82r=O z6|ogTKuwmG4{N-7qqhvz z6h-$`er%& z9I_)6nDf4B4X^T8Kv3z}8s!+HSWGezt$ajwAs0KtVK5T5jsn+0BF%;nfEF<*#OF(n z&_qR($Db~fR%-8R5r)q5T2=j!JB#IV-EuAYVb^mM6K?8+AmyS;u&-0VhlR}oF9@k>>^ zS)3z2lJcsd4}pByP72w`D0m!X3%X)j@^<*SXPMAmyy1Ltw%zg_!j0{6y6AZwco1kL zkt+^j_d$g{f%hqK!s8lV8pFM$|r}h3ix$!4|gbNOiyE(9h_u|0)yB zhqSH;Hi-;OA{Z_pUO8CZg*JHO#%_a}qeidWOv}OQu!tWIvb`9tt_`TcuC5>g>~vM* zfLGOs>YS@t+zUi`Nf}orX+M0^#^1x8H`_f6VJleYUZ%BuykjccTPE2jixsVk1BV{l z8~(6$pTbL1&B2TI4&cRBk?rYwg-+rC8Dmx*AVA)2(3Afnz%zPxAr^9#LBd<5&u2qh z+uh^swtx5+9_X&b=aYp;7S8As>(8K;0uoMs{B8Yy2c0=4?s!xA)z{TPUWgH2-OmA{ z0ooqcwM$#48rB!V^V_OST+HZ=W&X_+0w%PK5#BxYCm|_R({|Hu-U(D=9nnskxY~nN z0>IlVjM+9`%63|h1ia$&c0`=J@`p*O{@;~B8W^ZMcFh^C`l?OH@|b7hIY4$L6zsIT z<&f`a*chpE4p?DQ$`a7c(S4XNcffY{-_yU3I^6+YnnAl}aM=sxb};4`TLM5)-r6*@ z6a4Q4QA~3HJ&UbV|8?J0y{yBvfb)6hH1@k{g-u4eK+6sOZrh63O@tVUjFef zbl+ifY7;)w6Zi7!N%0`Gxp#PLbb~>)WYXE>a~$Bvb#fVv{hbEYQLKEhib1=p4JNru z@nn*ddiCF8pI{In{pr;i=_XRI)pmArp7XVDf^?=R!U9A%+`!Fhl#5wI9kOF&voBN~ za65S#Fst`i;Z#a>zFnsL=Am2N^u-G4SJ~vOSiAa9Lp$ku9qge=eX56lx^Mi>u#ldq zOyz_WFtRW54mF6!Wi#5>TIjfDr^NTWhGmvvR@Y~{P^RMrSiSfQUc=q#MfqE(k2N@M zDz1a*0cAq#Y^6lG!fN?Gf@6PqUVnanvzHUz>(cOd{e#tp86hk=R!^J7v)`GPM$mb| z;+pzy2*Xw$@K?Spp%-vkqXdC3-bV76%|HbWJMmQ*+U;{tcI(5as9zhS8$CpQLXlS= zsHBhM|DJ(;Lg!y|MOD)lhNri_P3P-Sa-Zs;VH*tS&;9s~-=koUu76(jPkS!+kX#`9 z>q${TpL}aO1t3B9*>=5?Fs-wG<-i!%d0Cg<{37+|KEDdyP2!!9i(wn9y(0Wy>x@(9 zO{8wy4Mn@@M%8KI1!6gON&?KG@4vv*Q-x*rr@>hQjCvU z$>h1i;dJnueef1mCZHbF(AFScrC*C%-BY)suuN@acRu3l{{52IN3&DTiIo^fHS*b3 zRwRR6dR^3$105A?I-|XUKxX~OZ@I2k2BOEbYkIpZIBkqxS_fv&=dx#E!iS7dUy0>$cfXdJS^=@aunXO26)|Kn-o=L& zblzo~hy-!>n_o}gVr6rcGpX@W7?<~BjQd6zMbZLTNc324YjE^`ZNcjJ3&@Ux0G z=WXwdfKy4r4F;!f1!$V=*TX~0%<0Q@t zKsNCUikt0i0_JzSYyq zvC50bf;_|Nk(a{~W%*UXVOJXcSqFi*p7*aemKMaFanTMRcAZ~k>gC~7z_?G$^9~I| z^yZoK6!KB7_T?OuAH*7ZBCt{d9Fog%-_IBz{a9N#C5v^*D=_sMO6|N{J^mfo+`c{J z$}ltl)sn(q6lDkO$BI!jPa2cMo&DYo!yLG?6Smn`w_@>eRR`RK_&&k&>5j#s#N>4;NPER~Wc{Rp8m^6$TL?|Jkr4z?fZD4_EkQu!+_ z`(Uxo4QjbIOf!Aku5sOkRY8@i+v@sZ%ADR$qeJu8&0j1F4FnS0%otTI;)ROaWZUM44r3L5y?ZoGH#4~PN zEuu9W_!F&aRVPL=4DL_xO&AoKwci;I;)d;ZEMzOp7r6Xxot==*lB;vJD5&=JH%`}~)l|WyQZ8)%@Tm9bwmTht zd;46=H7nEF!mIm89t^Dt!;B^4WZx|m4S!HIu^z7}Qb%J0s-pssf5-(!k#nKgI1P$A_FEM9 zm1<$GoF98fwH>}eU?_086cqJRs*K7?oRlux5<3FLa~Z^d3s7_%cCM>p4Majq zE{3(Lhm!v|-|L4R)JuaN;_*(VLd;)pyjsDfi45-{NOwEla#B0e-5y%MIzhA4kj^xB zevCc~x`m z$i--k?w23puJOwcVMSPMM~akJT@*JSzK%ER+7u(&jgpphI%jD*TIS3A^7*yiW|d&9 zZG}Q^d|1f-6-OEn3*?T}Qy!L=f>GE`mM~Wgbo3hJm8PM&&D6mbCsgYQ2se3G%U({1 zT2gUM#ZT_ALWt&Kn4|w1UMY{B?avLUGs_Y#!!)YAntavga9-c)Sp}@qZMQ`%*j$1o z`RzD+I$Z4_>7NnoFz;GP=`DTcPYIc}>Qno&oSKpB*xT(?K6&zx!ECh3&w5=b$G(53 zPZK?Hj;VVQl zBxT1Fsmz=f>fa6|(=Z8ZhLQn#{+63tFE07x&w!qdL1&Auk=(C``*$<_#!c{~DzXaa=+2r*|A=TB)>*jyI=sl0Xd$?Qwyc3r!u1A{-1NXHd$b&bgSGlBecq@x}Ys;73o1O@B6T2JsfY~06Tk%)5ec+Sktv<(Kcz}C} z?ulzFqpMYg0mZ`&8!c2@k~?Gk8J^ca@>rP-*NgjbpEG;S{mJ;0&eD;L3OqCieqkd% z97Cv$6CT2=PjHzS;w1`h?c<6zayGJ_N9*Ajc??T8ca5WJdBc9^rAfnV6`teg^!-qu zlMem>Y0Um&9y0f-jtkdKbgnM<{HM~ZzL=6|Pq;Tt&Ma7!Lx0!dNNahR)~nsBMnc5I zH%`tyYCOh2w0PM|d3rd%zC0-EEMbhbdpSQrM~Ly z^3y@=aexo2Riwu(MoU)};fe7W^>Rg@~wN0vl4G)De!4vK~As-R3!%sS&GKSGfVRj$nK6lvpopwXu zojS64S97WGH>VlZY=AoHA|27|klh#l9MbA+#Dg;~iB={)icy{<9@X{vQLPzOs0-cy zTIC&jq}Ix25J|c`a$j403|aoNl~lD^ae&Aj|SYS>mmm|0*Dc(S+=>hU#eCu z)p`6PjP0bn(!R31xqumI`yJV@Rb?Fwm0D0`K?l-%ohyv>Adz>P&-=ot+wOmp{A}vc zTpOEhM=<~jb0V8MPs|(qn@POY{Ytjky{4(uN34oy-By4bSUvxSe3XAx2U}oI0m`PQ zYFj$EZ-DDC3>JJ$c;)S}>^J|bH-%16r=!KK+aD0aWyuCH@$C!c+ z6S~xWEYQkdvxlwY-ei`6J{cee?t>tb+UT{2=l9ty5AQEPcySn;9WcvpPOgCS0O5kz ztPL}(R@fd2?bYP+eH8wb#w_*D_wOJ6@&~PM#MaCxXtut#E?ge>3biP~0U$VC&|R#1 z7&>VL!*=*vwa1jwR`yioLhKqSliOS-$NV-wy5(qa(n?5l(GBR;ZN-lAojcOGpM4~6 zc942<-=6fOZ>KmxW0UQ0KMiRi$ig)%jO-<-)QY#`-wz9m{IMHMzAwmB+||Ksdgm&A z3pZyLSD2R;eaBh=mKOKo?1>5d0J)CSrZMPl2F2lpl~8>l=6eUaI&*rp*0|Ry|E<)` zfT$&!WPq_Ra7Q1A)4|SNejU7D(X)9Buv%@>MK4aIGr0Ey@&i>oiu5!k=B z7jtdt4w}{q;E21>o2yPK5cET^^or{GHJBjnv+jgGfkVgE&8_;c@r*9^L+N~eFHYoUUGbZm*Tlo9><2}? zQ5>L5V61nQ;^#aPiong;d>)X!7B_@TNpo$}f%X94@Lq+SEcCZzRroGZU^x_WMdK#D zA(vl{3xZm9xmAa^+WON%hY-)(&B9m5zW(f#d(>|TXX}6UB?wwiH@gXrwY^I#_(9BX zF(~OET}aaxJ-PyB8?_do!~&zWs{m=b#(k8om5cA+tI)zLZQ z1~%2&!2F&|=_*Gr8l|5*o7E|=_xXEHUeo-q)rT0SXHv&-#}27}WB7^zS+dgYU44cH zYIonjC^!h(Hc}1gP1`547O-zktdC#@mRLY+*_#fK=H<^_gC9+;^vAv1r@#J9pRDII?;-8OT>b?|HHTe;oj&$xBfh%<+puNIIzhCve(JDz(TX@M( zg?oG(?f@IP(O^}XRQm3ggyiX|&$W~|SZTkNu4%b4+8>kE2wN?lch%8wio7%)0=Ga? zVn$X8ztZ0@>MRU5u^|u0C%JL334WYku0y7Q+`n z?sS-{+nl&n@@u90AY4qZmN_VnG(cZV^cS7A930siwAIBu@3{tIVu?PY)MPLy-iu9q zC?3C=tDc@c9RM*nt!EUFgexzoT3-$Z`ed4QeJC=#vunR~aeZ}6#sG_xBATbit*iST z5Xr+wGR+g3mVgTp5k&fFR*-k$;gkTxbh(_|mwD&8nD)J4FPr2Z53B&PTKLv&cMj{t zA%~T%V?ev+2s55l7)m+Z<7DVs^J=_}4beNBmume`7Se@>VMvlb{_X>|B6{&bNFYm7iaz1|@H%RI z{Z;)eiJgT#x7=cvKKmhnzdvWTT`J01wXkmnlp+j*h|dPw)_rnhiUyGRCGL8_v-;R% z224oLRQvITJ-O39#-#cu^Mbk=Guss?4{NKvIr|BX!~HrSwI7Dz;z zIMF6gyJbE4$Vyw`-PGqSgbgr?ZH=p?&BR$?i~h&q**Vwrn8N@cZc;g+%DV=xf#!;5 z^&cSy9Jh2*fhX1SSEBbf?E$q5AIbw;{0EeR;j*JPzDjuafO6Z|hof{@wzu{lZW;$G zZ!JJ^)(n@<^TDk8 ztv~2i-wF_2crAa^BN_Xr^rFZ0K1J;c@k;l1Dp(%(%e7nlJ4=lu(dy%H^9=8=*G!v( zp<<<9x^FIg<8go**6GsB{pe((9IGv)OT3Py8;e^rai9@VQ}>FzD;&y3Gmj{f{JS?%AG~8;k1F3QdUUAhY0`EMcPFsS@raX|`Xzm6AM+ldR!! zPkrL9s;&srY$B8aRZE`N{(^kz{41Fp$wE_Z_JTd+5th(#BlP~dze$-dj?T&A7A}Wi zSN>v)rFk22G5jny0m^vLfTOIupE>Q?hq29d`JNvmAJi-ROs669fT^ZXf;<&R#DrK` z#1B0@vwV)x*eJxN`|j~F<=FBg)7XaMWXDop-jsqim;Q9Numeg!^TmO=UqpYpYg8=` zkeKf&|DM&>M*-Rfn62WL^Eo0^uIs&O9g3S)RveEzm0sc0j#3YULG(8AR*Nu9-Mi}E z%a6eUy!(u&`@&(Dc7hu8bs@S)MuW13DQghV7QmoLyE|0y=j5M{B^S%$YFOMaGT?dZ z?Wg2qwH$qxW`!I_(BNO*d4D0siD^1FZoUB@@m>&z1lyj=Ik0|mSB>x@HfH=0I*Buo zi`lE&dP{a^!{4Bt>)s|gVlRk`Ni!Z@bCo*m6e zdm_*{u$Ka4Nm4OZdNu3wAjdOIlm`!WDvgL!4^&Qfr~Mg)6PPg=YeiNQ2+s zF6Um6aAb1uG{UqCj9?oX7CK0`pt(XxUT^tZ1HiS#D-!e$f_j0ckD%ko%JWBMy(|CK z3saf>0nR;1z}BW!aKU?b-2&8vGW!1I6}0cGh*-V*-FtVLluLcP$VYtPuO$~=v&uS0 zRH@78C}rY@MScS#Hz(L5*M!{?5Q#mm`!+)7ERG|P>KsshbW|@@U|y9HwH_?;?&H^c zQ{TU&r2TD*Vs1E9SeL_28vc1+{+c_~nJN7=orlSwu7fd7Y`|2MN9MpovXws-4iLe5 z4;&dElVOXUgIz96K)7W$i*+5a#7DN{-rbeBqqRf#A9qm z6ko4>9bkfhSO{P+}>&PvK5H zej$mH)7dHh0;s~pgMNjM(ei!OE6(fBbtH6$QOzGC=P@1GGpU||FIwp2pr$gH+V`fp zSnn>qnm+Cvb_>o)Zqv6H3v-uxP(KnRDo&(qz}=UXN&mb3#)Ga2HI*r5+x#G+O(H~jP^r|w_zSET zgZ**ZywEcqU^{p82ry_n-noy_JTFUs7^-h$<=SUrQ=t+bw=2U4~Vr&{ySt}^fe!nr;rKZDjC z$)JTdJJyt4VR3?zk{@V?)Y4}iA8GHoAu)Ib~JjOSrY-0(f-f8JVDi&p--nEY%TiG zbH<{l#jl@I#6}42Yj)ftnVyJH;x6$Zu|yai4rO_CnWy z=hBtz++j=U@)T4sHAnx3E?^(Kq!KI?^1O=n{pVpG{|&Z*nI5BL0{h74FVI8L25?>W1QZt7x6i%r zD3GIGW+X9?9hD`o*bOs%c9-u{qc|(gN};BLkKC%lX7}$s!_40wXcZFB{JeSg>|Aj-&5UaMjhZ*5Pd4|APr@+ex0 zm)Po3^qxGG3<1SJ`2uE^?ib=Q%8)u#adOBng8Z~|fWAl&P{w)wyTYWHi64~hRnmS^ z;VM0OY`Iz?L-kt?-8B+T!200)aUfG4ZN&Xj)Q{iq?7Xydqzc?Z1?F_vW$75N+1J~DjLl86C#>3~*1iD?%9xy1Kz8-#NPO-d+zbbcajDx+Z+<_E zCkN!KSIOpjVdOHVp(x_o+8X~=3!*P3a#mrc--Nzo)_T3KIK6eCl`G!THS=l(=FHcP$xP#drjVw^|kwj(pVv{ zWvzi}?R!z%FS!D#FAMAAc@`Z6l8$2V>8&s?POeDfv1Yr|4yai&svlpB9Di7RN=$Ir zlHZgjneAqIb%;H5-m_C5JrlF}v*rvc>rT7`ik&-6mi4bB7N#}Q^kcI1ca8gXy(#qO zT5Wsxm5dmAoiKN&>)GuQ+-|banv2dzB?q7)OGZ--8y>o&U!`TvmKbOiN{0`xNK@R} z$i2T`*qQ;HYlkzh3PQdY+ro0@0t#Y4{B<8} zS%+#*`H^z?f_v`))r=Ok=~$9iUP)aPyWLZ-XFJRZAMND9y4#~@qn!z$gFmdUeY3FN z)>^>v?J0j$l3MrkSK2e)y9%nC>eP(Xf0OlVp^8*{LgEQji?||*BIz?*p0|#h!#i6etJK>bTMdrs80Sja=~Q+0I1c*Zj2aH1@xZQ( zsd*%#{WS8sLXItg-tu0#&kIGt>;h%Nssk6qqRIO1?L(`=`!25_fxJ;OM#@`*-$Nm> zpE+cyA+c69ko0b#Qv}>{o6_+|Qkxy?M+vX|kD@ctI~NVZ@Da>GkW{vWge)aXiy}Kk z6m7KVPFqe2ML3V$0@dmR z%wbe2j7s(EIZl9@e3K}1i16(pC7(S|>MU{tDM)`2_Vk5OM);y=veos=!H7eE+ zzJG(NzY9#qGn#Ea-H#b`r8}SE^He;*?$mOswyqd<1k@apGR0x-a~7U;{yBRlP#&Nh(YIfl%S;S5*%Ke-H$Ink<} zt@QnCU48|{1^U4<7NH{kB@*!c&2E}7>X#phr_|DtG^i?@;b3gw+2qF)lMo=ahd*%S zWO?JJHj> zBrb1FXE^4?$~GPEK;IH6eE0Uw;l{YHe5sq80!nyA5e?zgO?_f?h4I z&KXV*L)24!BiZZHb+>!w{r&K-T-verO>;tReyls*AF)zyYNz)r@1j}#2#1Q- z@MScliX08O_6uE!a-D1^`X!%DJHri8Z^?|ia9);^emeVPo#T z$>RWus>3Y_s<>8%iT*ZF*Zb@J)hGdha`|VAw0RqfUC^#7Sgr7QIhh^urPJ`@aejw3 z&MMv=Tq83$#PUNPVri$R)5x}?L)-dQ1~;{aWiKT2+LW(R&_*vLZgGU{t44M47>FfPJ3pJkSU2GX0-j&$WgfF?a1x)u+%$IMvOjE!TQ zZuHgs_4VxI;l(twlU%T4yT0XOKg%Q<7ufN&y7^s4263bE$K<(1*5mzIQtu-=&De1( zk|BMRA|B%2e(r{n4ZsN({RrdX~7FL!Jw^DAInD=EMV0fSYWaXzof#oxZkZQoQ$&9Sd+7-E6Vj8;f zd_DXhh)~DGPFExsI5HFu0i$@J#%IC2-6Ei5RIt$oQVTG-DrZ+Vy;_0$`5q|bvso>r zSliO13yFn`r+?v%*L}Yi05d7mIDF{i8JbCna}_4)B)^t?SpfB!-x4-=TF&a&nu z#8lvhQKSJ5F^-(8ySX;4XKyu;^NT*q3(75L(}G0NdPl+3)`sXNMUXkbZ@-cBuQR4G z=q+pfL`shM;(9O9l~;xjb7Pu@5tLXDHy3R&dm5Me40S^FCwHUAj)rj3>^4}*T)8_6 z8WoT@751`FNz({$?)xb7wtjuwtssyfT7c&d^lcpb`C}Fyd*b&eRV;vn^GTq}^O8ls z0HoKhu-Sn^Jk?8>b4hdi)8NBj>vd`kt$c)%52G!ELGO8KgHa_c=Y7y6x3*aE9WK_; ztbtS~H|h3P?5fpy{{g!WUlZb7C^7RDQ1vhbihXpT_JA8R`0HM{ygoTM#xJopfgxr* z2E_AZsv{KjNZ&^HLEZ!&;#P4%}!+Z5}6zSm{*^-jx zUl#cCRA#<|x}8|%zQz?Hm$H4e{QLGv=OE@-S}^E9C8nP}?D*|g|Ib+-7&qk@o9+)#-%nVJ?a}R|HU#p9irv0F&pjGXJ)M` z*{e9LwDxyhA4;Rlf~2Md7-(Bg~hz+UFiHo8Tm7LgEfL#}e0;dWXi&Uyxe?@?+1(5y-Z>4*DY|2`S_zU1?>T zhCb3NOD6c!#O8VBn5XePfwOGN+*GA)Xl?K&H$S*{VYotO#k%T>j-zM!gR%E``Bt}NUG_6nO4wZ zM?YMNamy>-9O3JR0FQe*R;z5VJgm-E!3_xtveY$C-)G|sy{P_G%m0Vc&E%Dx)^(?` zVCGf*FE>Q$8&73B_Uw7}$`FnA?=|Yedh&zsj<(fXcHLG9@7?>p^2gjJEOhe?17E!0TV3{Zx9{)~e|9yu zDsDPo8S+<)8l3L~T|dPaQW^-enLD_3x?q7pdXi`ZQXc`!Fk`hax>5x>QfnEtwfD6$ zf@D|Jed@;%pFS26;Rsd2i>N``B_ka{eGUHKZFaAUFP-v)7KKrK&}ns zolKZTam_7+_@pG%l7))ilk1G;HG{kDx9WW&4{lnm>Q(Dlyy@zV>>m7;q|0bc>F!{{3Wnye`M{O6v92)9Zij_VwY`zV0-{u&vNcH;SU z&ttD;Tr6YFa6W!`d9H^IlBYj;wtH(b@3@BMwGY8zt+{W{spOJqN7gd2Om)Y6ul<*< zFY8e@<^aSGJ;PnU)ar+l5Z=G;v}j3iujKhAvHby7$9@g2?;siBe0?3YuhCEa?8*1c z8;Ol&z;PenY@6nL4PPkNE+W+>$mDKQJc*knL@`pOFulKGCsx{%>TY`LYtbi?e)YtZ zOE8CFQvUFRFv!6!DVvshYu7qgf)#N7EZvD|!^DYPSXGm}y4pc-EPA7l!XKe~ODNKf z2y|@zVdkAbOcqN~{e&UWzA_bp87j4;_-e-k`HI#q#ea056Y}-{R-5iexPK9P!R`Iv zyHX+bfB@^$Kd#DumEI>0o96B!*7Ab_3txl78^C2%l)ZHD^+Qb5J}?{9HEZy%UEvCE zF!mR;JJ?_S4?bxM-uu^SJoTiS;hc$NE?t9PB|g_T=cd>QgK6vCVCQp(Yu<0`s|0>r z2JBCmzpiM)uGGW|jhT8m($ivEw)CVz8=n=ngUVOKTc0{=GoLxV^f*wraI-K$Fn-+v zGLCKro77p04Ho+0tr6-2=%}ZniH4`i0Av!Ba35`7hXH6O)>LJ=t$PEt@!o$vz+<%e zWTLstxfLkh+~}2&?ks7AA{DA@a{-?Vy#)3q-Nf*&Z6gX~liITl)LC9 zuf0%3(iTrVI!I@*iVvG$nh5XxqEiYL@!HjJ-#qBlPy2JVtlFOBylvSSeJ-7PR3tw2 za|_;L;b?t#$8!GELmJGaQ+mx8{R3B4Hovzwl1P)4BX+zWTmetojFeqH_Xas&X)C3T zb1RP(oq%sb=Q1 zwIAlY#Jy-zaT8eM5BZS=ef3kv^VWTzUkbW6$YL##8)%>`I79`AsX=q+Ml5YvoEXn7d^P%(w;T@ zKkg{yC%&hzP_KpI>E;r2<`-3Dv*Z-}&AIf^9FcYc*ZV?HvGFB-NNc@JS2s|Zo+AIX zK;d19U$?C?+U&iDMPm^AeERo`xA#+OvVXPdXYj}hQdHj;TDKPe94b}JhM@o9y9TLk zvaQ|r-LR~gbgNkspBF;L7ZY)NePXUMxylW9pjA(~49@&wK$`}s?2rMa$&pPaP_r&b z>&}(&gD}fFwLHcbrh8QN7F{^xze|(tKN+_vxGd&qr8 zrOM5^mDVmpsmKKX57mwQ`s*3}zmaMua^{tIOPQ{&>>oooR{~-HUJ0NysdHjVVhHoQ2RxL%tNk?5qj~lA zG3THcCvXu9X21vS1%3j(VhcG!dQgH`RGcws>btpM9A~)4fJ2$vaIMwx(bdO)?Q@+Y zmbr9T?xXtQa+@MAz;`{#b#r~R49@k=p?GFC&t$uRbZyZ&Zp)F}ujg!>v2i=8&NvAOMH< z`(7B@%y&F7J^1Ypb0`kVn(5A0BgH)}^sTv7_TjXjH=*b<7SE%Jvaym2)wdT29`qE%*MLHs!Qvj#OwzF}H9eUtI`pk3d6*5sbT5+g!=YNyNvotM2 z9oBJ_4v5Yg<{ZjEOc52J#oIphyD0n2-+z_H!}-Dq7Txz(o^-O}9^KBd+id7Pgks!V zZwgzljva8zX)P+lSN#@oFDQ91#Q+tp+lPMEh&wf(dF9$fu1@dhV6X(Z!%&+Jf2Tti zo<-lj5x@|)%w`_s#)~dFIS-5ay!a#R{7PpOrWZZ4dH*&~V_^1O*OHl1_mMmpA}5lr zxL)0=E*D^^cMqmI26oref0*Bew_cCJyCUc()XDjyeNaXZu1iSr5pD#DJ$~dr!Ud(0;J?S3u zR#RIetD=kEF2$g86xWV*49*0hK;E)qHG?>P2mMCg|R684dM&w8(C&UqjoM~w&UqLA@@ z|96IzDVIAh*!l6#EUUNtK2WDEs1}Zya$K4Ko$Iix{oB9nAsE;Fa{Xel2S4U+tp??U z>kizel}^^qd!qSw@Wdplk|?>TSaYid_3V9TvmpK~C9Q28<-=EC2NiN=IQSOFu1%nH$M*uTq|6_f3zX zz8AP9nH|eBhEOd$-5_3;t`+pOgk5*>q&!7p!7rm)=C#Ir$`ADwJG_ynT=SakLB|*_ zs_;yRGPlDNo0m@5@ZE2Z3+m(D6RJu5l0|N~zE?F{2RL2y=QIdXx#;tKtxIV2wTCoG zLuN+z#;#syIFT98n^OR6Y0AW9r#Tu+=t@Fnb2e&P=V1U!ksb2FM#ZdCfHIRPL-00v z6qw`@*IVgMe^5vb&iosYslC|t$6&yV{Ofgt{r5U`QbB{ES?^SyH1kvM`+G0&iD$g> zH4zllVsGCj%Yt-4uJ4Q4JPo+gd8g&h9_HQk++>Y*XEfW(IjvCJ5KJ+JUQ*S#EJdP| zZ=oPfeg9pV#+>d8%M4a*li!a9zGVl-<0fFxh(miYtFiJ&jW+Avdmb&NQ*}D4(!iMl zj(B^?tQ?K(^3}r+&-2ODDVbA?wW0n9v%Z1iX+k6UvgOx#!E=wVq^L(lUE*x1-xhxD zkzhM#9ws&C<^R98!O+>(Z8%f1`i@mECq3Q2oDBcmOQ}|LQVB zi#r&=~M_^nXt!PIWk%yN|y50LFzU0N0&8< z8ooxw!i^NCnAv)EFG=oqUU64{SX?K|aMo-k4Sf@sx!j=kVA!RgbjIz)v_oy|;BY%GkC?$`DF8!*3E zvlS?@FIVGM-Rp@O>Sb;@imSEsR3nCu&$8jdL40rYsaGSq<8--|)8(o%#fv+0&_7XPT2zm>l@dC%( z=ntw$>+&JwhU3M+(KV-==V8vLb`?pPBuTN_aevPa!NGG3*zfCWYMl>tWN$TizCY%y z!>d)v$vFoS{IxGv<~!hnD{l5KP0X4gG6X{6V87hkJ)_62Nc^EPmG{qw6jYjj${-GT z+x8^4k;v`1undb-4Kj+IaQ5ttfK_qiqW<{wPZoSFEKi5m8;|X7oh5!Lr`#%=-sXx- zMEmkRiu2l74adzbn!j8OGhdNh>T#F~XM|Ik{?3@fAN+`U^KFarX015kVA9K4ru!S8 zN^U0PaK@Nax3f=fpQ|tIeZwcB6-m~vGxl{h>%;aITi-l%%GC7TgCSOaC@HM9`B@pC zC(9E^P+I#F@`Hd2v(PoO1ycLgwEOM-!S<~!sY|ArE7;UrN{Ah{ny;mESeruW`J5!* z^cU>7%fhTzNjtRC)k{ySE>Ff*3-$cZn0xn z&ni50d8XOxM~^?u*Un$cL8wVumd?s*g6owCyj zH?#Mw-2AnFKf8xI=nL+Z14rIE&)20)N%-a)*8SS(ND#RLLJ{Ejz8uYx|EiH{`APAR zmx1JuQK(MoG{j~r3oqxrL3YMBzF4r>a*NrPN4e|5_#t1@IgfIu!>w4pwc)ov8-lI@ zWU+NY4n%fgWT&7c_ATo-$U#n`(U=P(xlwVW`g$=cmsiUoueMf)kDfHD*D@OzFTqpH zDjbv!Eu=ae9vk{w+3$d9R9tPt@)^b%fAHy7zLB$(DcXyx8!JZ%+v|)mIuqUCL%amW@Sp8kAYTW;%1GxpzS?j%AIPXzh)QGBW%0H%M zJbZ(JC(Ny>F=7dnzkju=Srb>JYOHRLQ}f!Pi{^gS4V#k=VdYZU{h-Sns0huzf986O?l=L>`@F@#KX!x(d=QOC4LSBq^OcF)uXjn%&RJ#i<(*8#V@k5$6@tZ4gvZIBkaU8i@Kq`#S+|Jr5n;kFyD! z_)6|dbL|N=S+G24ekk{qa{sibZKp40zi83R{^B@fCZv8f%%#+t&D{qY7r4avmJazW zo~@%_Ee7YxS+4X@id}Jya^oDC$r}7gmj%qmqsjeVnZ87#Z+~G2eW|PS>D{xiuq8#a z@k{aX+#k`yX=>Sxdu9si$>%-NA4X}?=e}bMyAM=YZLG=>Nj191ZZ|~Y8s8~d{il3t zl*H@XgS_Pyz_>xJkHV&uVdHC4wJ2+@|9SQ)28Sa1C5q>KVG?2KyW=Kp#oT#x|GxWT zxA<4?>&0$QDvTfSYa7^WpPyKKU;9jufie~j+ru^4L1(`RQ|rcTK&0m>=k8u^ydN2@ z4Yb9SiHWSm@Gp85D~(j-yE=Tu9v6`P*6q0_O@``4`?I=B8`dGn=!ZcZXH*uS!xNoJ zS%nM_pz@quC^5mYow}O9F}bx-PU1mvU}O`}mwdJMM9 zcyvBcv^Pp;&}Fh~o!krchsVW;mU5#POth*L?wB2Q83>X1-fKhk(fwNvx#1uD_VdRY zQOO7O+?0kY=2VX~?S|~}EerbMcf77k=o8pt*DK_ey2bq}DiBxy#>VH;rIX6_WZtOe z&nB6l@O~M#?VpXU-4`c_3*=JbTK2d1;XO{^2_p%9NJrU2LH?{--+Mz+ars`~+QY4u7rg68pWR_|+wQ)1EyhUK}6OpKr3 zn~zuZ$-9mHaDtFF_9$H3!dkeBaQg40ElJSo52-#okDH*v#1 z3NAhri0_;1ircSxsLcLqqMSDoB$!qXXQ52til}Y&)4SS_khZVX4D5J{D(fA6#0F)& ze!NP{-Rd3;4cbN;vvoMxz_bVLx&6r*$#om`$2Vcv^FrsiNII00Ef1ZCRvnW1UBJ4v;d7x7 z`uOM^=Z&K`E%2_@&&p|Kh#4XD|2W4J(2nRxb6WGRRl1!(`e0^SNF8Ye9rx-*Zi9=nwlo-s#uX zYL+iVe;zO)AD>0q>+V7jsAhw8nMaY7W;+q4|Fe2Z8muWya0IPn_N3?62P?fTt&bY#1|~exv(| ze)_&xajwc^H9GrkgSP&$2c`a=|EiDP#JA|uwYv{K?foeT)HB+B-mv^e{mxYP{hOa# zHSXO<8#*&o7n#sJ77vsB&dWx03b2T{RtZ|$iG|~R~ zIM>@q4=oVy!2Y|~w`cG}_Ln@^7M}RT9lag+Cet%ayUC%~vYncSBPRh?m2s8mc`3D@ zg`>u~f07f9`hgIW0ugIUdezsBpf;1Pwg+t9 zVh8H~h25(fx(cVO-2}VH)UL-Bd36cH0yejzPI39pTr^@6ubcKb}c%H9T zmfDNWi*(0hI-Xmz9IFK1;rP}T&#hovV&ji06vE<9dH2NHRUMu>V+VP?22?RmR;Lja zm+>EeU~zXt3z4 z#0pYBnLG=elUCMJI!3da-eDiTOz7L|c5Aw5J^(x*iVptG#%;gq+WnMgLzNyY>E<{n zJ;tz%nZC1a+sPM@`Ft0h_VTd$StmvVk+I`qT1abqx_cSBZNRahP%%jJlq?QV>(C_f z9*)k+XZb6>>JHtqlmnbCo0e_*X{XSxy(N!)NzndBFKLxvOQ5<~owe2WgYF+x)-5)n z#tF;OsW>ko@-tqq)<&V+jNcu5n@vDzW#7g+QQ*+Q63}Q$ByR=!voVe*4K^cgR-ggF zx%PwcLof7&L)u_^E)Y21b<2T__O1R73)L!uVeiAfFIx1ieSIMnczoK;&#hKuk8)%* ztx-{)xj6GHHWml6x;!9t{4vSgq0;jxNOl2f$*fH(dt@nq3%eV>pF%!g-2e82QO)d* zy~=e&Ng@h#fRb;l@V35j?ro|=<|4q zsg^Q0!LDbakFR*-qD1KP&egDzfc6K2*)Sfz-c#0Z}+fhi|=Z(oG8y1L z-C(or#q*_A7ct=}H%n3s8GgXu`Vcfe)*$fZpo#c)qsfD3rymtwC(~DhR9b9h>St(TB*)%JD4XY(uI?9uLmvWcI%eWC6L0rSsb2r-I1{t zU-JSV2cHYM)+$k<_3o}Wsac1|_Pr=|c=7&&UeLcZ&B z;dHNm9GF|mbiGh+ksl*k_YSbEexGK2r-kO(a{VLt$6W8Q>rJMOi`c2bdR{suM7=0j z8)V$PPdiBnXOxNpA&W%|U%nyK5LOeg> z@&v%ZVFD-wp^Fn;1E|GPg*pzHQkAW#RR3$2^2%~^c*yH>?=^Vxr8O5+yT0uG;0eQE z*3I0)jybCp;eYl$XTq$6Uc~c$qn|pf$#QVgnL?#Knj9bb%bRjIogKiL3CJ&FI>RLm z%HzDuT^4%j`0eoqqe5nQUM8)@R8X+w`5s;2FLuGIk8o|}s?BBej>wKam~lBWKh2RQ zZN((YpZdk@`1?Ycr~wGS<>DKS)J4Gz`j-SD=G}d#6V2P&^pneKIZVZD&e*-~ox=gR zR|2xD6@$M%-1y|hN8D4;aqaXRh;6rC<*_|(lJ{nEYwBQh=jz~FA}Zw{PILTkXA9Sx z97D3b`s!8XAt{=KGM_|4``zgWN8=uktdJ|2J8_nWN#B!Q-3j3-oUNiu6VkAyhYx4_D56m^6Q4l>522B)}^><_0gQn`|ELJrgy)U zH=mQDuzlVuS&Nz5z8M?TjJQ^MOAD+$<2)xrRzVvO^OYX8>CfzU4c%pLIorPG?aSX5 z-^EX;F}{+@-jJcfTIO}u_XW?tCmkF8V;lLf)G-^6=6t zIty3mRR{SS zzU+9JTM77ByoP^|d}G?cm1%tfw65S>t-M~xR!#b?3wk~2sh#`{cuHbp`U4&-Td-z3 zl)J2Gxy4PsLQSyzhAXyyIZcb$hlwHiI4$)DpFuD6pn-2te|F110^OZ1}l7pwK` zZg|nHMKvjWUXW9o1?y7Tp&$6u?{`bjLuz5_Q3)_B|=> zn+jg*z!h&;Y9irbxUy#6Z9Lw~hZM2i@KH59iG(#FbzURWKJT@Fs?llTCk&-Kn)GNc zS9~b0iG!$4qHz5JP_={f0Q3r~&E&~|Rc9QZX)@O-FlX>ug{YC>%#C1zcct)Uj7$k(B~yZaHoaKg>Saq#P4>AYl&Bo@EH&S}p+VLB>o zj)(<3U&$-BBYk$)1D+>V1Gjc0UEHgk zwk>N8S()=Ch=a)cFK`_M=6AEsUBG2764weddU6Gu^q~7WZ1;vg?zM+T4kCQ zDt>1yq&avaBZYJ26ax|CIhKV%{eAF}!N15hGuAHGann+C{3&5GT)MJrXkKmZ2+=!5 z*qCLfE?XFs8laz*$k}@F24$;J-R;Z*D?HD|v$N=#!|>(*q=$SQ7J$-f%cbK zcOf#LPoqkI+|nUefSoqdDJ_}(iGvFBfbLgAXcDMvsSFG3mLXaYO8;i%qWy#$79>)3ECrXy(7V{Dpf1{`V z(Csui;YNGcq^MPHhRgb{>odjuGFWxD$!G}Qv4;;+q*f|rU(-*Tt$a7Ep56ItSUvc zK~jp-Lod&+dirRq#d@3aL@$@zhsL->=Z?!{^i~CYqQlfX9+v?_l^A9 z2bzCtT`repKA(#I+kr&dB@U7HJ-dfGo8xb4#eQa~SeIVsJqO{+_LrV01ooDSxSxac z)wuI_o_V?i&tze~A01&vc0|1sGZBrEi8Lb>`_zun#X z&aTZRl6Qu zssE{qy!58?O-hKh(gpR)&>IsBM-rzVE55 zioSG!84w z3-!5=eY`UA#bIlYV#zpIa_<#v>7iw_z2zu8ti+ZCETDwip!qW1V@ATK(72r^UqxGb zLDsPG`Uo&cQ{>Do4@8y}rzf?(I2Y=g!pxhaj-Zsu#*(sN;OFO0kN4kQ@TVkNmGbEczQnB&H%=Mg~k_2jyg^` z?E!P*|3vtXB*&pW-Zy)vbu(*mReAZ9_}xt_T#mW}6L>pZuUJ|A0(RkE;*{y^Vz~i> zxQgovG%GVFK1jjg+%|Zb!2Xe*q3ESr^wYmN?u-bJmzCvi>rxa zTs9ze9}CarX!n>eiHPPX`B}}_B6n%TzhCciw4cGJTdT`5w32!0y{6$bo|;|Imhko3 zCD!SCTdZ-%dg}ctpSXQKZ$31$c|+CwlgryxVU!T$;+T%`TRjT)^Xa(Lv6h~R5wB0W znZg1gnTc`9N*~!K8eGbq*R^mNoFP+PJeoJ-i^+3DA>dx^`U{I{^UUEZZP$07H zgC~5)#2;)#o-csym&@(V6Kd>ykW6~i$^ZOt^I0K5nDTKFnzSofS=4Hg!i`a0p! z%8#MW^;YLF_-uAM?f8C~6yh{94r@j@R8sO&z8`nt4xapuQP_@yPHcbV!g24@jrrKC zE-v9hk|GHUk}D~D+mSvnaep2-1Ln_)4?W6uHi=pSMMhR!uWIj6D`m|r(zR*MsYSWfYTqx6D%nTaWn{`{;S_yOJyagUlmEKsx}(dG zD7HW1HfnEzQg-#Hts?%yn?YTYei%DT8WdDQ7f*D|n+-=S|Fx}oq13I7goy9FJ=s}+ z)uZ6gg}IXTp3258%+FdqNaq(;Tn- zertGIUU^OroVxj%$@{~OhEw|Qsb7J4i23RQq*~`68;q$Y7Hnn`S|`!Ry`}#A&r(_2 z`Bu`ZugqP!vrDy5s3+O`{Jk!5$nCTaW=U91s*`lkPa$)~r`O>0Lc-R261~@j$!{xd z;-Y)W2|d0#xb}82k@_f=co$qTW0=%oNB*{bDaD&KfPoBjrUv8t8~5}we9qM zzQXSc{2HS-`}`b>pC-&L*Q@Vd;t&u){7qT1SZGB`I_V=-NvRRoXPlHiol0(2*F^Hw z_r+gO&$a=#z3yw2>%wLhuh%b}J^!Dhb8RTci zwLkCc+SZ)Ydm7Ie_u#)>HJz+j{;*R|-s_mHl3t@bRv@&l!ioIZ%upC7&468%Y;Uv2 zWkP--p0swu%JL;M&DM6C%4H*tKXeZ)FZD_7xxfF;T-bZ$y7J_jj+aaHx!tUp11z3Wrz_!htY4LBlX1AEJwe51S!6D+QDq{^$&QDyTQV-z~BRpDXt%KLXN zy9|2sYpKTaAZePj9+K}=IzwU|I3azWwgp^&G)N0ftlMK6Fh;XWx^|U6RZf$CN^g{c zpa2E3&rg5ny1dre%4BmA&tBQU@vG}wl2}jd2j-DE2d*ttOz~_#Bf9f-D8aLSWgR7| zL!Kh4%{q5@4!(1{dUwE8i`Vmc;Wo`@qYXKWU_QR__doETJ*r3R0j{Zb-wuUGuX;(D z14{T@tj=Jy+^tVh5aS$WX-WO}aIpIIeACJDSPaiKNu}RUZVa8e`%{1qTMy_TPp)_a z)Zqp}pJ2VPP*JPw)6Q@fF#aL&F}>t~Tb{`KE$`TDw4j~pLOuyMt{vk_gZmA6s|{nY z{qKDWXG&duzek&s(+{Fl`k>4Yj^OevP%e-Oo$S>^!lFb`@+G?i>3Yyd254jQ0`5Ula#HgGm zWSYO-OW1L2M>J#Z?F8=dr{A&^-SB0unJ@)WMi))S?F|ULVmo>qU;d2R(#nW%+k3Lh zPWiphcE#|>-;u|?&|MO4@@>c(^HK|v+D6{^Jj@3hTy4*oGC#)BUv)|WKxAMr9(dUIH z_FuIAJ%ic$-PUZ;@0!O|s}U8{Ex<#9so!kN(WFZWeU5y$FdsL7K2-~D`D&aZ;e`0? zj*Z_ZM>MJp)=|1GKrt~9q&PSCZaxlIdUXXzc4qw-{(@;ImMZ`Me^{k@uDWQ9OU%v>dhtd>>e=4_Wk9#@;!xmQ$6PyyW2LXK}>074JAhO)BB|k zF8=}f!1h`nHPX=zE8P~a+JSrKUi5A5>);?_0)(0v`Y~}=F{Epc70o|Fs~2;8nAq`d zl>Nu~Q@q+!b9eMYhFI*{!7XcC!xC9W4@!Q)VfF58@}QhvUTp;Aq2+41|n5DRv^Bi$JXem!yxTN`7M}g4R=CmIhiX^9ndYjxkJ50V1!`N z#T7r8jhFKdDJuP6>VThV;;rrqtQ%=}1#b7$sZ)J=+zqGy?w0zdUEY3?xAhtfnRhzQ zuVd&xFz)ZE{eHjmH>+3mG>E9q{DwZ*+c0m< z)iYpH_@{VTD;MSWN~@j>=Qy;MeWds#>xu;s*fIrp;HssDVf#P3Ox zJFEvsRBamAt<(7qAW*F_5`$x_?#wq&sMDfh?QeR$$~by|2!LS?PHx!5uG)KB$-jEn zb9o%5>kX9fs7m_XFN7$Y_NSk|M{lIg*kqd!V(N;?c{odxvukHN-y0^%XUbZ%k}3Z# zv>#`}qHv0#&^vw}gr^q>7Tb*lwLs?2$wCjd;T0al%~pvV_w9exElEq2i#+su3I!|g zNM{CnkP}dDR#YD_f4|C2&bnrcET(ZmQJK7V?BbikDHtQ*hf$8N#X@tKt|1A9J;e4) za@@kGF63FjjG9T1cATDPGIQ^&6LM@?@eTjThf1NhwP5Z!THO)=jpRm(=(JK)D70S5 zNz=5T-YC4GT{!+s_I>z`8M3y&hCfz%g zcJ0A-U3a>FrsRT5n;4gEe_g#-H|J~r&x@z>OrJWuJ!R+6bg%Rb^=R_L%@he2y@d9kaz#9F9abL*l+FoKGxbWc;qLzYwR7)z^de*ygtkeJtb=YF(#gEN$~2+ z_4ncw!q0*lnw0pgsMIc9!;jTo>oREhH?$?L=;ZpodClwrP^Z&hVFzWL*aRs_Y}QAT zN!54{dQu_wwA1A>TibdkznlJ^0i7?A!VvpqO(@(nC|-g$aw=-wA|%G+V)L95*Nw5O z*Zj%3giR%Us@<;2wocD_-{u`+!95nM&7|m@_7z)wmUFUKqh#)0Id=+E>=`wAgzo$4 zi<^AR=vsOicR1Sl*&4oMvtXOi}z{&$L7#Y{Y!c=ODm-S=Db6-xZh2y z!mClCj&b>zN?__{B_ucZQLb^A?uOZtkGoX&g=J6tROW@4g-l8VE$SlD{KD(C+{Wec z_xJaG7Dx49ipR2~D!VWH*af!%epzB#YuN1SBP{)z<4eCV(DGYO{{rQ0_iX{BT4fGB15-RGBo_Su79H3H)8KW`#QC{8X4@g>A=v+&Z}y|4|(a{91E7 zyW7$jg7;Z5J8tF|@h>-WMu1s{m_sNeMEz!dEOx&E?`Ief8pzduCE9r;;l&8M@5aim zJ7FpCkQD2e(2>xvE8S)vRqq;*sKAH2{_2ZW>sgU${BbFuXmucRnWa(BL1o=AD|@vWhzg<-zU)d%d9z$0L*fhUSWNTj>%V> zywB6t*;-Wy%*cKBtX%?T)H$eNn@Kz#VLDWq&|l^+ykCoRY5raaAO2l+t36ays=lzl z8?{FA>IHAV)2rBHR)+KCoe1P`usFYC!Y@eg2VGA;7PlN*RA<*7p4&~_vEQ@TuOJQB*Z~@baE`SQPW`~kzk)WhT31WfNa7;xSZ{y zFkGz6{j42+yjHVNRhKGB%j3dMJ2XEvb)h1F7aeN_7l94?Fj1Bmv^QU8yy^Zfz0Xf@ zZZ+;CdE!XASku91=;T{ls6{xZVVXo&_>@b{+4Auuey86W^tGMeXZ|yDHjnDS=OJ4D zJ6ms?Jza~XQA2x%5cSLWYXN&{>aJuO!6qIbbIq(F-{<8=u}UBSHsY6ZSt5dG3jNN| zAm5c?VkPsH(K4o-_r25$rcZoVtm7%Xe;fT4k{yKUw0s<_)-VP_0gcYAxiQ;X&KK8# zh>i~+R2Hfi@l^Yc-*E4j@)P&MGFT_56nRGu3a2gopq(cqQeVZM7_4U#@;#kYBm4Si zZaw*`nj2x59a2rYm-6qzEAZ9Vpe*rg*^0Tqa#mcWz8a8q5CGBu7whU3as&0Ax|;W2 z2b;)dRiSxdU8u&1p+5~iWySB3BI?bf!oHkZuLSd^clk8o1q6#kIWx|)0$BVMrQfZQCxqZCe`2p#9y|yNF&*KfuBE%U+B}3 zZYeMK+I^Hx*P$>d3eg7#Y(HWPag16eI6JkmQvJ9qyVjJBciQfIwK+se|1LqX zr%cQb%eY!aQrGl+Iib`otNsdB%9vB_p_6xda2(&lz1g14ET#&+r#8%zQi5~TgL5E2 zpLs4DGaw8+2WSE6B3o~tWN%HRIwNoD2WL_+;rZk7Hk8>8ci+QL6NK5K?oTeuSD+AD z2d>oyL08*`G@RFdn=k#W#^3hr1AqOy&Nu#Ys}n^YkIZ#azHhzdYJcrQLFTW`#>Lkt z2pZ=m=2zs&$~gBAM z0A78r^33dcw?d`^eHWt9Vhi4WGMzA;+)*EwP69li;GWz_G`1IP0JVGFh0-6SXL*4RrzAHwSLWuv;K(@7GLyBH86gzWM&y(wA!1uCN^lM3`M@pNZh}S zR#B)l@G#mFyN_OnTVFJCnH56n4usP?-X?DO(O-w#b<$0R1DqI@eMid|RDf-z%W<+e zAoICKT$^;$pa%LH5Z7+u>~O7n@Mm84odbS*)UfBQ++9J>W<~B^TuBjzpiv_&Vw%cgKO=_mvW$5+sGf^>Gw+S7Jg5qc}Oh}7%;Ss>uCx=#{}T1bBYcdmg*};CGWsyPEKv-;skqkkfz8m!w%A)c?T0ruMvY zGX@=or>phOrbbs#T+%07j>>5rY_3r1E}|C^R&V8U?Et?-2}s`8+G-AIb#j?Z8 zl~(tvJ1rZjB8b{Z3(=qT);e{zE9CEZMU0Uio{6n*8BVcYf0UF0CVj} zFyYTO6_i>pv+W*U;t@)G@1T)=Nv-x*Fgrnce<1U@xo{(Pk8hI){pk5wMYJKx`{Qsk z(tYHDKs5x;K2!4^E`A-Dt5#p8Te;6n1wh zJv(3PS!;a@n^GBVCQ|#Z7p&VJtoX=R$J~n4hWz9ZbEkV?nJO5!FqPx)$P|TYc7y~o zqy}QPV|z1FO_4(hWZbGKd^fB2Ujse}bIYIDY)rk0KUClPVQqPQ<__%Q_JQA>?U|Dh zlX=rb#etMfw^LEdm2b^dX}YdmWbmY#qi_Y>LO3fMSAnQrlBb6CSfXO>XDYOgOSj2y ze=!V_Xig?|3cT0oqyNp1W)lR!Zu=ovAw7cssnLdQaMRv)ARX7>xj-7;M61safc!Z* zh1Ici`0BG90!~O$Ey+t|@makbaBddc)$Y!L$;z}eP}TC4{~G|-n5D+cSz}f;?p*Uz z)bwUECQ2wCt~0Ox{&?E_FdOCMc$G9W@zD+V&SBCruY5y!OG{L)f(PFA#kWxTJM`5Y zXSIgpMS*U+I8rzH=)>!7b0}saORC7qG^xAAZM@ZEGh1y6Kfjhs`^9ot>1~B_hW|aM zZ7Piz<3~WrV5a$kHDUMj((^C+K!Teg0E;e|kLO~V_vrLa)%0qAYNgF7Mqk!M|8z4S zM7!%aHdws+*$3(b!ekQcoY!IiTYMRsEvA1Y(r*5BSV~I83$nag_sM?b4d4+=4=**C zzX*8NzV-|46}Vc&RZjJb%xgbB7uaDiW?u7Cwz&=E&5IJwgY0W+p@9)r>6_iV}e68jn^@Ujs1E7|jPxO#2K!ND@ILpndc zhyy>r=44%#1*GS27@5by$jXT6T34hg$VYmD*{$bf7>sX zKCV^t8b)8IqOE?;zEx%JJM1CMOn{=<1W~==bflk=+I|djicNC;hK|3!^=r}?UA$jv-Dr*&^Qju$-V8*3nn_19*Ov-& zM;B(Y^@H0mv@bg0=c-wD2C@YOI{$kD?+lFTzPJ5*te0;A!xqAZ*Ljwb@9KD{e4DVS zZ(|Z0Y>oi>R>r5oR&1~FFN?@&=fm(VRIlKQYZC}^jdR`+IY~eY`%hU9!EpR3xYV;f z%Wlv7Laf+}KVVi>rmy_8-A&oE7jhdYxuC)0z0g1KMy4-CXaxTmxr1o_l6UNp?SfPw zOKiD59OO$uRy-{D${4mUs-gF}Wb7a9xzMd6Fd3|mYM%^EKF<*XB)1PnmxsUU7rYB} zbC}+<<1X-+OUA)XNwcNtadtnP+%_FUaD0}r4X|vAn`ki?V456D zPZ^A<=6s&vz!ed8>EvJHVc2NL#`?P0=azfzQm*SWmTSJYD?bv*5=;`$wQFI3V&ZxU zsVhp4ds%5ZJ-&Jm&~N+CXTI#cy>6>AiAwT?7QAzM!Kocp6&OBZyAzFvwg;^3pVL)V z>1J6wR5p{}rk3l#ujF7DfQwq^V2+#|t2KFYavihqmxze_yLT@(H$hwBC>9@)jK7;z zA)V3(L?~!=Fp>wZyDlEy-PzJ9s(t_3D$V}%`7*xUk^JY8M>5@HQ0z!c#AKG=BJMDQ zReAS*r=f0*er$a}5V7KGSEzMr9e53}a&xYets}Rg6xXu6Y+w1Rp7pj*D>~ZiN9*NG zemWmX)&9DC{N_U8vVvIQB8Nd()6nFgANAM1oHzj)WBgKX!@fsMpg2EqeBFy zFnmQ4Y|bsXVBc5P;oE<*`^l=zkaNvD&s_$eyvM^e-rl+fB6nZE;eba`pT<^tMGi}blWE1FYYf2RKowB6WIZ^99a7f|hHZ2k3q8fM6J za5a-dW6^~KXtJkI>$i$td`{X1W5PIAU0ye$8kgP;k@X+GTaOM|jpDeqf_a0<}UOAYYkMKTS8#pTn- z)81I_?}7VXToH*HU3v-T8H0 z?ZcJFffQJu78e3aus!}G)sgQO)_#kBLb7o>XRIS7)c#iV6Rn8)lk6g1@$S>j4cW6G z`@BX(L-`@I?RioV9Kt`V?O{UiPRXzq_wg=sKT6w>Dz$j%(e#GC;!rj<)=jyvPI+{j&1RRO=SFBBYhhx5PVD)=- zR@{w+A5~bqE;|iguV`yp60FfBk1|g#xzX^|1yz0P_q5)g1NxU6;CfridL8t)ot!(a zJ1y6~!`>t!KE*>x+;*FYPL$#t>r;}e>*w9?aO~*pymFz;_dJXUmjm`7_l}gJJxDpyK zgdDYv&xp61zg6!9@Q=3CsVvZ8461e2nO0bJ+u=V$*Keb?-`{|k=c+h8+K$iZ)l|Ec zD-UYxlg)%G!_+-PS=B)GmaiLND{Q{QC>%tmh5Z|^Sk59MSZYUnE*1EPaUp&>nce+0)n+o!)x7?rg>b=9r zn%4l$I$U^Re=>NVxG=>Y_0JKiTYj@(fhO&+xjcRQFnMn>okJC;%HwlQ>1{Ss>mwTv zUE@YM6q)Vw=B)LNzftco)_Y94{T{tRYsvS)l;mc|?S2+6bL9ciCu(^p#GHn>h!*?Z zs$aa1Zsq!H9gllq06V{9_pTl_NhoW!X(Qusvpc;B3tj#u>BO={o+7^uTDg?G@Tzw7 z(g>ws(H|nnoanSlKsYA$nHMHmP3jGl$YP>C_)}Pja7hn@~OJxnMcVSu< z(Y)3ZDoOC?-P|;(sbbJRjD)+3H!-XVp&Uz%JcDBlu~86t*uwC*-I4wD}f>U^bEwt zQ3ajf(Dxj9%*yQ1tE-Ey^CIh>{n6ASp&P?(@Tbw~*;hYix;Fa-9k6%D9))syFe~;d zZD2)i#zeQ^)`?6GaF^7uxkv|N3C5Jh~z9& z(=@9M=6^SBtV5GGWZy8exhQ_Yc(wyP5ClvH)Bt1O`+>I5B!{!9_w!J>UeQH`aXhC5 z)5uoUaw(ZrrpK6I8^Jj3HA{ujLc1@c6D^|35+vF?5%>TG(&qS2q`+@E-r>$poX>(T zuOkp=dz^2etzk23fRwP9W|8oz+dr_u`1S^G7N7wldbyYGfc%~kb?k^MQ{h(I$c%ka zm|yWqGraP@GP?b9uG_W$gz%I*0mmIQ-1W!Z#fz^F19N4A7Me8K`3Sga-_pd--is1c zAvMUj`9@AI`0JeuyWN?qcagTmig=EaeUkniIT9Js^KmODRw_)En{0?@YQa4~J^ysj zV5Og_WS>s)kdx;dL~v1WLkw%#B42Fxw?K_bPj*0a5%AH&*KOlg%DvT|NH@xnSB%x7 zc~JqS#yp7;24Hbeb@k?xAAF%c_y)yX?xzwRv_7b#+_GN+3NH_Mi`kh)*Y943;_9V{ zZusw!w5+Eb=+;HN=p(C%;y(KRMdhc$6JJnN&t1~USoN>F^Xm9M9K?2GTk$5AMfpQ{ z8MZWn)1lM!0K@|`*L5D&bq*-CXZ(N~PDbBiNmF_lrT%(YUj>)PvlZry+&fy3sO1c| zeKnx`BivbswDy@7`M;ES0mKacbj)KOj^!hAM-HZ0WP zMje(P=4-)qa8wp%;W41z^$HOV<2MIy$qzAm{k1!F|0K4?M8QksNZ*z`lT!UOt%Ag>+4)PuLH={&g<6 z@%s*y_sYhI+Mu-mZ3qncfGhRzJ*W#7OT?G*3L7#ch5h`6FR$q)WMd-3SGBcJsuI5PZg$-)mK$H+;SEEckQg_Ke20 z-LLIaTI()HYdH5S$7%yQf%WG7j3pMPafVn@u6uUwC9MNgSd$`gMjmWfa#gIRBF|c% z!o?SlTBDje`b!86@GRM(%)PB@OD3@Rk#iPb6i(T?haO%86yGCr)e*!mLfXzA_IvfX4i zFE_ww1R#fV4#%^;^iXcgkf>~7{vtQlzZC)vAg?|3e&?#n=2T3CZ`7+$Dlz@DOhl9r#I-f$}OccF?4?ix3hFu6&5!)2d5W_6VzV?NdGORhGQ_P%t#yo5?y)wlvSEad7) zuRxLWL6S6@?foh{u~GZTKmUZ&=2tADGnl{(w>1m2z8-YzbUTm5b+ZP`<)4x(p5)iJ zI#3QOQt@Vdwu`D?H}u(?8NSI8&5~W(yZ&}Bv|p;OK8-V0j%%R5rNiWy>v4WfaBODM z+P^Qw9SxUUqIrSyg~TU+)#;}V4@t!AbxITHdkRu}^DwIBx=x71?@j+IViA$ftsREl zlruLS*Bg66q4?UQmq2f~dgzp@3o7Sc$J~Bef4PXaWAs=<$qgV&|8zKC8majJ7tM+Z z6Cbkkeoc zGrbP_gZrp+kK}}cTf?J}Uk0u01WVCSwXSW0A(wJ5oU!R$lowiTEttx9 z*;~!1esx#vEhxb#ua2+wJvE;tH`09QDm}y$PVPQ?+Q;(UJO)wm)`&NKBtLpR`4^=x zfi}A_s!>(}ybl2{zCHfVtwIFA%)`G~Hy$|)JRqhbzIJ!5`!LR1#y?6|86_#+t2%%r zkQdKxIzHPVS>xzU~Ik2YXJ#b4;;8#Hp!Z*Q%RNaaiQ>r=~k*nzJ=KgSk;^90hXQH8+R zVhi_di6>@k(*KECfs=);xS5eFaH&cACe^n`>8kPCqTdQs!+Ws6)i{nkQ z*?q3c8b|zNsVdhP(XG92_>O+QosT;#c*^5;FO&Kj<}U#e?5BQj5TL;??mVw$=;xY8 z?dx*}!xYRT)+gal`r+(0nj8l%+TE1KnHv+&;p2;P1)E}vuUAi#h+gdYsbtsocGnxrq%j=2pBfwE$WUa*)zHb z>*c*+N`?StyQOsRzjM(zD^Efu|5rtIMY@>z+I?nsiKT4aMEP5EPTaV5?zV}nX}jVb z$8wE!Z$7=5lK>lKxdZbMMcdyP=^|s9B$f(LGa@br$g--C%a4Phk`|x@d;&Z!Hy0!~u zelvsnW^tW+&WAz|JiQ0J9(D2>^u!}!LZiZC>^Fvmu#d`R(}AY@nzIkH-}rd2joESN zwUj0GDeXE8TmyKTRPaF8apqhz`u#67>~6okC+UJ<`Hx=4D^zbtO?y1t$H3*RZ8D?% z92{q$pHs)1uE~{-w|`c|RegCK7}Q+c5hwcmbT3tPeEG;M{!JPgS@kd9{HFKq?hGncK%jVPu_R_&Xu#)sBM6wxX@=91aGDKCWLg!eLw_Zzhh414SGxG(DB1n zO3beWP-SjEnBK+bcQZonQ^m7Oh~3htPumU<(XRFnf03li-ACi-M!DAP{k(iu<5@1a z)lM)Kb@5b5`iou}ADNTr;|pD`C{LXH>%-h z#{Lvo$*%^x;}`p*Ft{m!M7VP|KPY5~D)pXQE9|=5l;j&iWnJvr)${2E2o`tJKMtqc zw#R%XQbk3pt4oVFzaxrEO6f($j|xZK%Je|2_L!q&;Q1%@l*Ws%yDpK7Go;d1qwZoj zzYjZq40jePb+m!?He^v-U~}t$&t5FbhDiL!eR73}&R);gY*(U2Qm2Yd@uBTZM!9l* zmj{UUHG{G=9k!^ioN4WFdq8(#$K&SS<2Rpl>=tfSOq2QjFQumt6=CkJDYf39&-E#Rw zdO_f(lwb9RM~&KDn)natCt})~e4CmhRREbku$hgdm__2LNx4dppDq@|#^rYUpx&}J zVUYJIu-i%W1;gwYZ9cRWLZChO2QkY}+z9pC?tqyqeO%X>XnZ_MgrVVG+f&#ndj_rPdAf7nxf5btf_(p)UP`#bM; zdXKg2?5&NKN^XzA9shC~eKs`j_8^th4L=$fe}3oKq6te68#Y(&Jo^=o6u|?peWrD` zL6t+3u;N;2SuY*x`;+(0QysOeaZ#1Ol(p|o;;zx5LU&uOhFAwgES;9vYNwA1`DbZf zU5dz^YRZ)w%Ibtu+wEO7dey?A-lx#A2RjUN(dJ?5Lu0~Ye`L?9wfaZ}MGt$2^&T<7 zUj2-g=VdpGhx_Qln5_AtV~RfxwG%Sw>ziRU()la(Do&SsfSu~CQ(3A$b4dNQtLARU zA72e|IA4ZkCc~ioQ)L>T3G*!;lo%P8qIQ%dmw`M5xTUj*u@Z2D(C;vqT0NttJ*~J) z3|W@Ns&n+Z@aNs_EL*XoO1!{c@sHGp{Zrc6c8q*7JCm3P&aTUh^ZSz^yrWz;n{Lpk zOC zpG+U4qBFX{WMtjjA(HcwY(Z?Dv&Mp~k##O{p&q8Z1xDO67oMQEq%WQJ2bjH{dLc3z z1WtNO2crxFL7pEKgvkPrbSb-HkfxWY```D2*xYILY`_LLhj@3c)%Ty5%Ok07Y{XUV zS-;F1*r4s8+2n^mcLI0m^h~MuyHvFK9nO6^IIqX}N?GXe61{#hTgXep-(4nKx5mvl zK@XUKN`AiY{FR{^qNXiJU1RilapS*Zd8fKFob3-w(bE6Z43%vWN$>A7%-TP`8-R`H zoUcKS7$|4#-=e{HCr+R+oIh48<)TUcJmtKqj6ZJuG0)@Y3nNA%M`3Mw9%D!L0PJC_ zmM_`c#T(N*Txsxo&N7fepT-Vb@Zbk~mZwRK?jIzR4n>CJPc;Zw2PE_m-wXIczww)BzIP)#EbQ!MpIqZP8s7UYmYcL& z&8is~#^C*DKFY{+k*Z%tE%l7@T8SyJ>i^?_H-|mfEfLxBii9L!o** zb{hG&DyjlDDoVU#eDI;Ox-N&$Y3e!PN?jQP3Z`1YROR5@S2R9tw}+GZwV+6kXI^cd z@0%wf{*wFx!LrJdKd+VUm)WVIwKBXAWIhi6E1IfW5}oW|pzRxQPTPxX_liQr`>ni4 zc8kFl%Kof4=nDI5wBs3?S8-zt0 z-R{=(&qbP~af=-_N~_Ie3~b8bA?ecFa~{oTGU#&j0SjcbhO587xBRo)aK03SReyEe z-21!v2*Mf8v41KqTPKGqr{sZnq=Q$u|HB|;#76VVP)beHX446B1N_0$E>v%IClw!U9O8)_sw0C z7`A9z2+?qfd2`j+ zo`*gLr`Vvz>_03ySdDUIL8u4)zc)%hHj|!;Y7Mmc8$q|{ z!L55N_q4+jaQ%g;tdq`540;sn^gGn7by-;IXB2o)JsbTPqT((QN2{6BUkx}=GV_JD z*u9tmnukJ}v)eeZO>d|WkzR1_fM7W)aOY=f^nj|1InuG;pHA+vX-wNNzpns!FIu#M zeohEHSH3~Os>uCM6Jr}zs>95&s9)_3GSd2i7~pWWSH!bY}m zS_@l52}aN3_o&5c%P7s@qMGaAxHZeVBk^(#4}WL*zMbq#i`|$S-_nXXuO4svv9>x@ zWP5B?pA+`Jd!7cF?QBmhC?tUoo`7~_6SE}wmI~wyl22i;pt{WQ(z?wIWk`d`^6=L@ z%vx*3Z3EnM3+|)pZw;~H0oU!ZH!U9TjM_{TwS#V^!rwLwels#;DsxS$eJuom_lwR7 zubc?rhtBPyaa3v2Uiz)*Rz8LM>bSl_W|A7*nNxAa6#e`&D4yGUv$0~Xe}sy-?q#zR z&eM2cNBW;UJK|I2d2&ijwBo51%--$d>D>f(NBmhC+KR{ihDv!1&!9?T7G`g>;^(6Y z(mlLKWORDffz1^_R!8m-i+%<8wX!`qz$Ci#_*mFbF% zxsdAudF%Ur@9QIt>u>M@Z1WV@f?odWc3Wbt?XpM}qF)#JE5iFlco3`kdVGzxOnZ7m z9@1kfaMM3y2l2`(%6!-1_7fZ;Utc1JUUj!S6`M0bROyA6K2p0W zo7=({(O3LFBcKT$Y49ABAHiEpn}vT*>soJ*o7XKqTNVIo$o|#{2~+R8P1dm~ajtF# z-eUF9erx9VcRCbLYFe;Ey*#6bk28DP4V9h!GI!PGgI~+U6Tj?klX5G`cZ-F>iQb;XDz0S&*MTMTEVIBlAEjH|7W;h4*a?^V+Yj_6X? z&Z}g;;JMJP7%qyaxhik!6(JlIIjZ~YAGculZ+vG)8x-x=RYJIXyCGYl`k2_kw!5=oPg68r4$vV6Gi2lC`Of_`yEnB~BM6P;$SWtpEIg%D)HbvH9HPU-o50OB%ehoS_O1Rg}4W-_Y;)Eg;*s5Z z?z#I1iW|6Ts#J?Z+jZ9yT3EVPd??4VWZifLYJ?iup=sbM@6e{n?J!O(@Oc z*8cH>4)+&gVytYl7Kj54f+20ht*BoW<)EXFtUK;k+MiNLLhz%HaC;z~*T~0CBaE)B zI!pO)I&J=SEqIGHr6Hkv>)yl1v}z}*$_jtTk8iVf+&92b(7+*?6;rfTfk?n_y`fIm zVG=LIGU_we#BJ1luTaOx5jDo{Wl=1?dZlV>${15*`XIR)lIls#!`v1Dx1jG5RE4;ge;>FnZ4Qj(t3BEm57RR5SRtt-@XSd3QQ$_%xc zekms;!)Sao9K>brr>JhO_apa|-;2I=o$b+kOn^EHg~XdhNYvIPu0@MEP3n&tq{Foz z2f!0zoNO-SX$%Px%)j~aWtjzubJ{4FcHar2eFV0ARkJc7$AeYk;kkOo=BL1L zwwo$)9p(n%1t@13Hx;^}0{;PL$#3VYgxt|v9$XDKi(3c*Bvtlf8!X4MhA;2b&iTv$ zBBHVpbV_WP(V#f@qj(^#ihtc=e4LJQarW7GV-T(GVV^OBDgslU=9(jWPF?AgY(xR3 z6z~!2&1)`yJ6%SBv*ahe`+BmAiqrCW+^gl(>%2-fj+OT%=&tj$xc(H1g``yUuHklH z!2@}qm3DpsE9HhWHYk{D1b%nmx2)GT-6ddvb_T_g3oI9pi2AcQM=<7?}ukQQewyNNfVD zJlNVOvK<7~dsd1H<9a6;#1C$^Z|b*K9sE}{&H#?$;an8ToE{MkwsC{|aibBQN;R1s zOF?KbF*N>lrn{m{B>)lc*IzL4rb$x$xu64}y=NQKr4~o0{KCkoqoM*#TDo0HBy_$0^e4kg~@qM{c zwM`dClnj(G?E$BxDq|Eyc#bI#KYk&V!*s4^3nU^8D@W3gcS!fENX)$k)~r{Xr!R5j zJnXm7xI??8P<{8t_sNfc+fgC+(Jjo2%+jHDRv6uRR4(=J$OL1{0nU}%ZwUCUztYWG zTxP{_{nY_c3751IsXL87jH^~@T5Bcr`Sj>+w0hD6L@JMzwyQoo z#aKQP1p54u*^z@uwbSjHFTCnIvfLkhL%e7cx0X{Lb!vD3y_Q(Nv>D5-Q3ovnJ#I8? zA5W?zkHjwM)+bD@x##KHMc;qsy|!2wlcW8fCTtb<$pC@b7!*c!M$`0^`%Bd%nUuF_ z!ysV?($lfp(aE*P$yRQ@rWXxgDbm<^&2y@>R;qDq_Pe{vA>N2N`*1In<2g9tt>FPt z>-|H=otIjnX ztJ`Kp#hbm$5Bj$*-PPK1CV!rcf8|CSN1p|4hHn?Bc zl@$J6dhHlycEHV#KaKGoz6-`$!-8?dbaeR!CfaOJz*ycG#g)_gROhXmj4mfvd$?Am zS!`2d(_ zR4%>T?r*(TuX(^PKMg2JY>A%o&0TjN&d-~u zBWshBQp{dXXIsnp`Dyleec#`?pCj(1lbiaKX3L=*8OZ%b<#C0y_8WMl7dNGgZ>xKc4s_q@im#gCC$_PP#LLdXD`R%eB?)|+DtSvfY- z?oTc6g(w*M$u)*Na`i%_&IEmi+VdPWcL>nT*5dUV`Wkd*kGW=T0f9D(d2WIE>4&u_oV_U8DYT7+HH}q3|-io)U6+LWBHLM0&--LI&iSX6M zOsH4ic<=lE6gr`El4 z&!Tbr%?`T+JSuqZ(F#jdXEoIXhApR}l{5;U&idvULzkYOhr8Qmho1;F4q9PuB0T@# z+zHQ@()+O)>eG~P|EBKfXg9JMixiWUF$===D&C*UO@L~q)m>}SJtwL*ES|tzUb$^q>vd9GANCkQWcAfs67;a30rS*3TQ&Yr) z$z9J)Xr$OAJ_nkcUX<>ZkoG0&33Gr7v$B0?Fuq$eTM?+=iV;Ze8l&DcpYOY&#ea?Z z5c+YMIM>yXlI{FJQ(7}x@uHt~*N4r~Y<2&3TKMSlsg+w76Zy)0hJ4L0PpuLxi;im4 zt0jmXM#4HH+G(z)%uY48GR0f4K-?K64?r6KjO3jLQV*N?a(-vz$U_Z23!82EJmgrm zaV3wNS)J|L<5AF{iU4Ath@d@}6vC`;^)aX&xoDOze znEzYx-1_8`r=OHV6Na>y^4@g9We5qo%1JQUczIsb_nX(<&p?Ik7SqncY%H%!YehQZJI{DiWjqRk;-#({p_gVTwPeS$8_XqmXsEn?^*soTf zl}eqi9D+$95^keosbgnH^VUG_pQMT!D|>&cL@lehEH@v zN#=w->Idbn*TE6%5ytYO^n!d7m4@Xb0{U2y>ptcE_GKvtoQ_eZ*Ba~Dp4WYul4^0H zi_N33iAEGwh%(Ru2Hl=JVbIEfu3p7{pR`m+BN-#_q<=hT17)_$ zi1xF?F>nG{wQ*+sZXC@H7aUxGC&cn^5P zg}XzXgz;@OE~4|Y8-qfUU!Y$Jd%$K$oUdOGb99{-z+CfkaiLru@+~^8pxUnoC2eiA zGy_7>Ju-p8w7`=-z1foQWQjwjI4*~8`ik8(qPn^b!`T*1q+owuxm9o0fi)SGSKU^i zQ8usAkJE1mU-Y{71LEeOtfp)N@v`2@2uK-?&Q11LeToFT`f7T9)-WoTOl#U zre9!ij;2lC6ReH3>=*F3G>+<>qk#N-z6=4qXyVuu>9@dZ)roTw9Aldv)XTrn+;1k@ z_s@2)yKAHSu_s@#TipBHpjoJzXQou=?JugK(?2(NgpN(MOAD`dE*EC?k&EiflIzdk z?DjKYr?fQwA~8C(ey3ayP+gm6zuN9M8bcS{UeFU+Pk66Qk+{^0N(U>-4$_afzPF#- zYp)Jhz@p_Oj$ex>>f8U;Yglh8941|0GT0Xo&bKr0LGP9~;KQ^$9J3L!O#3_`K1<

                  ^|FKuMSOq8Lh-&+} zD4=}L_yTBn`5Cc;DX2Yj<)T%NN)JL6T*og|#G@k(r-~&w8}`<4=Y#D-g*B}V?akOQ zyQ>HKoZ@zcT3~rVgze3B+8Jt1w1aI#a`dXWWu$)plG9fKQR&47aEhT={jb7er?Q_Z zWcSYW-Dj)aXDRC~+a-%43BIv`ZtL#!_Ve$J+AZDHm$~V=#E*2gZc(V>ec7pZ=vkum z84J-R*xUKvUJ3Y0;c@&!5A}V1z4CJ}9;ONSAIEbf?YMAxlK!-NdEtd_y6fbk%k6Ou z_r>>Lzqaq(XNdlIlH&U4G{itU`1!myO_E(wy3#ryX=gPJW+lvOyHqki##!t1YqRsu zoB!MQU_VCaqy66n+5O~O1q|{%rW_ui&6A%Q@&?6B*Qt7X6Q4f4ajd-aNAVxF6pYErO7)~~L3 zbT@Zp8gGG0Uv3ShL>(QPi+yh^ml1Cezp1M-0~lkYGWXB(q2=F=UQ{e1>T~+4Lw9ZY zja7Y){2JZc?~vLbtn=|(0c&i|Iz4>NKdb7M?Bus3Qn zr7+svZo|9{=gQlLojm3nzR4&ae!>XFNCw($K2D z@{Xr-c_MV=;RSaz0>OBzV@MFR(1p!Kf8 z#pgw#Lv8ZN6Ld1wxw#sF%Qfa%bye-=z}G}G`i)!fOBr4w#qozYD=l=)ypCftbkx#n z;>HUwBvsJuiWk7mEXHw||0an(YBE=_D@}X&^4%(A!QPvd&)lpr zi#lhPPScJr;Z>!4V?Wy>V+ON_EgybY+xP-Mwz?BitFSnf3i>39^K3foJQ*`y!+q(} z=i^kPmEDX9oyV<~eKtsr8Jyol@6?zaTtuH=z!b%ep~bb%{w}_Bf9C&i1j^;QQzbmv zoyEm+N%ENDX6Vx# zmDxl8O^M?iClU4MUt{T@)lprbZ3^4xE6ZqBDSv8=&vqE0)5%}b3Ij!z@0r4Rd!c3& zYkk@!k~u*k&&f61ogSvw*uHk~S+*Z#e$&A6)L#2|m3kEjF+UBUMA}EAgL3(LW6zk* zgHE!pFbFkm@7*D>`JOCh#g(A2#GWb334RhQkRnJsOM0E3SUA>7%xnrt$At?ZV(`N} z8Nw`5+wNna8q0#&%pZkq6%FQ4HivA7_C>h4;Fg*nqV`e8kNgozRkUaf)B`drctUp$ zBhl==Y38yW(H%9o?Z305GAq5AhNXY|`?uH+9S~2G@XJ?~4)gyfzAA z?xp9*=Zqb~96r#IV~94CAbcI`CSH|}gh?!xrNbGK2I_g)DzBqzQ2(ZtW*uoC@=Q+| z-_v`Ac;}(U4ZPM0ITar%2OgbyvA=fneoa1nh4%T`hhUv9w0@l`!f`+Xk<|=}_NaOE zEv!CweBc%4suH7w4*6t$e`V_Sq59eQpGGh((_wAGbI$7nT)F4~OqE(Xv~iKFfp5L= zmQrmWugJk4`om#>-!V4(A|JPfuGP(tEgy*wM3HCF#ub$0*~C59#;~+ni#GM_UHjEV zQVRRV5hcs5Zyeo7EbFInaR}!ZFO=zK$^U7$JvXPM7)BBkys@0gW}K9a;yF#nSssy; z=HoAnE`Ew!*8x?2O@Cf*%F=i%{|XyaX!**ED4}jUi5VWb{ErG&cCnX1wUfduIcg9T9*-6Bj-fR zc$`CbEoQlH&3EP{C&Vdr7;QeYnI=dR)*%=8Ez}BU+x4O$@zD3d*`6}dd{%yx=pNb! z4_R;6{1JaZ(JY`l3@p!EmOEWitTL~%XS|(J^RbG67L}$$bl1_~;ZIKGWZfGq!X zv=?Vqe@L7Yj-=E6eIacWSnlfNROuQolt1PL0|nxp+}#9f-+SLDM}FDG&=E{V2F(?o z?-S~F-MV=EW7K^34FL8H_hq}+N1x|7+0`3^7xd#yfxZuOjLlYd?YU4VSKIB%BI z_N89&ON%YnIu2K}!38`6HEqc#PhX?17r6~Cwf)0SA6hRMm2-fa*oidZPV&2G`L>9MjP|u$bSbD-5aAMTL?;{@nO`y~bp- zH-N};HR~+Cg{NR))Lz?2SXt!Kvz|9dW$MeNmMlg?tt|Cf>;vlPvN#bDvdb9$_4a94 z>^5w{P`P*2^4(s&vKe6I^X#6#)vQ5h=YUb@8p#d1!z;@*Um<_zc|Lm3gP;F5iLW>3 z>8k=Y8t7!d?Gx+u@A`MF@(%o7=0fM5??1*2yBN2C;?>?tz3}rr{FSvbzJ1x@(riGi zW*i+NqDRmOQCq@!e0yAkn>gIiDn>`B7iSaWfqa!@#)~(*{he z=*83p1jNJ|OwJW9=W<;E54+iKMJB5q9^iVv(C_|gS^xJzp-L6HmF#TN6F&?SYzMq; z6{}{SlFDkI0>9J!`%4e$9M7LlGPf2crD7=iAv6-ms_pz zUllr0p>nq_!J5p~%ge);Ud6Io>eNf+=Ig~o39hS$YxVS=GzWss{T&`#PA+fmJq^%w zCHXSZKVO+X;nAjG;`2uFIX$(7eSx1}R!wB-)P-H+_fY;IQQn1AHSEWTNP!*1Ym-3r zccFwa<%S0^3PyjGiCe?Lu|>ysRpqKC$M5?NV_h+)qw4)~t3b|~GW##z0~SUq@| zp3;NS-Z#m&-}J!|iW`lEGt`c-8!v#+RFRu(*j`MJo!WlYo$|bGj=BIuFj>zw;#Jkm z|45ZWli=rHZXO+DMNY=OYBY3XV0oHGPYs@XLK#3FH*P zai@u+i%v$})qVK`Kt(TzXcpp`YTyqRMm%A|P4- zUz>Zec7G}?;J%zbbJA*G=l#p0H>(%Da5cFtD`)LHdP)5y_Re*y)UWkkAUE{^;f3*U z9gD_2$q;lS?V(`CN(%X&6e zAfSC#YU%Iw>yP`jV10GPx$!Cgt=syU3&WFEB3R|^3#92chedu*XaDn$Tiij6fwyZK zfjN6&_Gy1kzn||lt#rc>d8ptW-R*Fx62!eapaA!U{*5DLpcBb^8&e_qICp% zF-&R2&7J?h*F*GcEvd!E-lO%>8j7m`;}k3LB)|9umjx*EOuh};_+G0mx|Yr47;1ZK z{LicWzmL%kTZ!<$|Lp(wzMsZ*9?ryRmAzix+?MX#gap?9O3jE4c%A&$C^!4u{b`;1lSy*+}4Q{hw&pJ``}bJF#j3Zj@?4x6 zpWPl^-q{}egGpl^Y%&`)5{yB8_6x>DU3pKK zadSJ;y~Y!BHhOyeT1dW7g^14zUkmE;n^KK%ZlAVZHQKkrF{D}J^}N!BmH(o_O2jfApTKu3GXr^(Mgm@k-afm+O=~?5CKA$(D zl+8NdVJkyS*Lw(T__u~axuF|&zx?Bm%j zm$oyT*uOFZRpzB$v$rOmLsq7>)vr-@J zKSMA__g%c`2-p=|ZP;Tom5Fx3C{42Xs7}T#L~^AL^rc@(okVsWgEzZ+^Xi|a0~G;r z6x?kar7a?i8*-URZc1PKYoC}V#4`#HZJv#K#M6ms`y1JMV8*?aGDgf+ReyX^k-IdZA1 z%%)b(3-a>26TsOoRk`mE1NCa@QBgDufyqv+3R};4d`KG-&C7%|8r$-E%|9LsiEZaN zLlPGoC2eK05$BfHtpo^MEl|#I_p##zAJdcJ=7Ir@6)MwzK5w$NDbcM>K8T@!^^iSw z<3+Ct(TQZP5u^F}FNvcon~;RouH8q;GmjZy)c67zIQH=`Y!w=ZyW=sqKYPesVF4Yf zW9-&e=f##VVh((-*Iw*QQ?E>~n~F9C9PnSOf0c*UxW8%|;}zNSYH#O@so(tM^K!4Z z>{%^Ac*|@54gQd04GoI#%dvD$77?Zo`uS*D-c|^3L#+#Uw>Rz`&C6UW6)&&*0*wa3 zjc!hlqZxgnu##xZ#h(~AcaDX6AKNr516m)#2^SQLuGF2j;CA$yyOeh7)yIf4N(!|T zuQj&M9dVb|sv~%c&C%U{1sq;soUH4+E1yLsV_bLq%&Nll5_hD9y_FSSv zj{V79g_6GJ-Z|^3thnFTn~uOr3+vckDpu!FT6_ps!Zh-u>l~mxTI}-Qp)^NQ86BTYiaRE7$Ccz?{uv3z$iJNgA*G`C>Mh zHc=RJSf8juH&UVOQCoAvf1AZ>MTi;n{ytP||Nf7Ivh zcl}y6fiA+n-a?hd~s{*fBZk|NJZiO|SHq zYo7(^yC2bCJ$IF{1Rh<1Ly^*%}tjw2!+q;naok~StXxFv}*BLx3 z&A&I)*JBhlE3&FoK&SOp4=P4kA%W6K@&5j+b=Kxfj`>yL+@rSg;IR1Ny{G zOA83_8tM+ux<^!+JD&j$C0+~Qvt5_7KYK_gk2knFo24M)2mIUVsKyC~DdTYOaq zh02hA_M*OqXm+L5n1p)$LXOB`x4>R_1YZ1A^LBrFgY7nJlCi!?Pd&Wcel=T_<*RmkkM7U~={#%I z%0V5HJM+Z_$+gfy6uSM@lzIGGaL9f%)N>yyd<$>GKlI9dLiV2AT7}u`^0Ir5nBH4w z1Et?CLx=U172fF3OoK05mhyHWE#`12mKRnpeF;xJ5Z_Q3$xFip@oM1#{31Eq(>j-T z8_n%{6@JKPMY=OlIN2`;rJHPmri3kvQED$vp8yA5;JJGm0)fD7b=PRUTqjqHd-Omn zm{7Wn&??+a{8+$Vod$rPX={rp;e1M~CnVSamDmH^bMBR9@8ZyF6$u(UmgK^+usOhI z0klpZTX=5pgxQtUeiqMfz+@G^^>MA+XxCnSlj^MDF?!6*L0*l5FyZ**D0k*iUV8t=ldy<>!&zBts) z(37=RcapW{)EG@HmeJW2O|^Sx&NhAaJg>Lh_G`Ghb8qo8sb|TeXmvYds{ygB#(JUq zbCPH1_KfR0BCKPbhv0Z*Pi$0YEO<*7-))|*do48C=U05|c*ZN&L1Z6Hy4EGPrYKHB7Ca=pVf2Y(d0m(< ztf{5VmQS_p^U%>8J)f&-MJ%@7l;vOIA>QBTpG>%~%x6ui(3GQh9plp6VBk=AuR*U; z^;x*bLb{KH_Nk3(SL-x9g7vuZhIK5ujS5t_ZM;pXEL|(9^^61TJd4TXF$S}w#7uiK z-?${&vN!iaGH1n=b@OGSe-Di43$2h->+W(W4EDwRNB)e|D9@G{FO5_V`Mobm`bJf7 zsP5ad(3g+Hxyz}1+@G{pYcdAF@wh=PuSNVlF&^{X?U%Nh>v9@Wtv6AAD41BBe461H zTaCu-YPSikOE6p5pe1li zf6%OsAMz>a$^}8Bj6y)HQ>J>7YQ8Y{0=hbX?d+ys`c!$2{?Qc0ASFa;Nzmv$x7*X5 z`aampEc~1%@>jope# zjNP(QdD^2_<-rI_OjMG_*%I6R(!drT_=IW?KM=0v##Jd|_S~~zhW|=wU!HJ%=YOlb z;NP*!9@2p6OPkzEK$Ad%PMMYA?&I_&@ql)Z$IgQB$51OxE!X?@t%vQ$ovyr66~M99 z{}v0U&rGyjfvqi$^B%Bi{rrb^He2q-3R5&GuYH?T?!`t&{KX!{SwrvxzANVm!~o#* z3K}s^V~JUQjSkm#aq36W9ZC;hz*PXkq{x}+<~%b=qg*Qkzl@#_bGWLK>(O{vAe|@= z^W;~>!1%T~soBI;`U+r&xEsGpsYbQq$avT4N1$hCn^}5Z^xHqS_P!1Y05O%ds<@vx z?LrZykPm>;-d6ugx$QoEr$}l>8q;fWoL|s(y&?xs!g=(>U3syCvf4*(SQADF9v!nB zN5Tq^tLvOvfQc1--5V%a&60wSrVV?B=W1^Y3ffEULEBYEdi@-~29QOcsQh88{PvgT z1K!@i9kKqd@%fkrJ{Gp%G#Yo3W%UZ^kaNt&s$IoLUIaugU0WZ)1zpb}*U2+6#;-Tq zn=}1x1xP?jC)0}8s8Or@%I}B&g`FIE0mAjCjpVBBu{JHTMe#3>F9YmJ6V%`_=lVQp z?95;3PVUawEOyj#c~-ck@5@3%Aj^{-mC;%mHxK0E100I`2P+Mp)v2#m`PmU$k9Wus zUCnBxa>MS=wB78ak+1H))N|%8L3|5AwOvQ&RYU(ZA%iJZg!Q=C#Gp84Y>Xz2Wzd*& z;2*PHKjbPkPoFjP&>8xG>inY|7istiy_tG6`R5|r31y6m58v-M#1yLm@cdE&mT+L| zwbq=-^y;IHp|xvu#jW}aI$;R%T<>`9Acz(2F8)gkuA0q~{+zpW;ai@Ri@QNpGe>`v zzJ66M?PFmx`b%5o!T$IBxkn)XP7jUsCgj)My0Y(|w_2&|s(%zbx>;>7&aZVTt}hPH z8-=p<$r?a|pZTZ?s>0L(QXaa`LBl4e3Zrbj%B_cNnW*R5g|pAt&~H)Zdr{%-2GEiU zt!olu6)TM7be*em{1Lz}&M!1*p&8!G-O|ZCGZNGJ3T9A#mKVTz=htfzTxviY%N&d8 z{3(8$)?nfE{%+q+$Q(%^y5g1^dvWRYcd{@DJ0wr5`aHvX;@ z%8k`y`&I4)6QezA*(zLoiT*RUtqfk}_3P1-bF(_!o^RpX#gcKx<)@10DIYhl0k$7% zlREfzFzJ1i3rh_2{rJ3Tk{@N?`H=@kU*tKOKLHPFBbbgq2-b_~A3N1b9Y*yhhQ>Wdr191$S4{ z9>8-r@;9qbx)^cq7zH)rK2FoKad~M-*Wn@t2hkQgb+?0aVA|;U-cTvX@X~C#rM*^M zp3houPkDVVK`j7wbGyG9enuehDNP?3^cqK6}d{+mBw1C^(*)<}>c4-7jc30p1l;OMt<%%}bx=SvN< zJXZmMK#&wn_uhCAth;+L-o=g5Szqjz4eh$&9_nmxr@!pC>)O=Ls^umd`HouXvp}mt zU!<>F^R;s(r+!wsp5e3b{IfS~Mc24IyCvt<8Ip!=RgkrzhR1I^%k+E!rA&)f9^Z$4 z3d;keFc~en)IQ8d3fi5;C(TPWTYFLD`o1`f3NJ-d_K}ClTUzBvtLTD*C^x^|H^)5` z%CfcRzRnf<_IQ(2qESxEmlqj+yGwrWbCJept9vgrnE^R{)bCITRmWFM=}Ugw@8Mg| zruz}o_M5~evtHW8v|B@deXf1@!d3mkeJLCO>b$zKEv9Fq5>;RJTv}Zdmj#>@wxxM* z*e37kfr||vtOSp+f3Jc2T0p$c?}B{swA@bfwsp6Xr32Dm$+v9mvo^Fh?)_H%UtT~4 z+XyCB=8R^ESIWrqMH)mMqEjMb@lcd$XNbwe{@km-kzD&?yx-L6T9>vrk;vkBhq$?Q z2hNq+ffLk!IP8KiMpZtib`G*A9M>(jQA)#6<^ z7!5dg)BQq;&@P>fN3dExU#06LTeXVA(#FiTy?mi|4~P3tDPcKx_oQSYoLGBOjUDuJ zln2*zo-Y*+yFK(yBAN8nS|VAlyGneXVjM+1cF(Oqp z-*ovSOk7_li9~%ZSrsV%xl;Rw`!9f%Kg?zTz|c+0olH(;EQc|72-TEd8v-?k>t~~V zgSvuAvESMK-FxT~um`Wfr&!`C_SIRM_C`OxE9QH+nf8_Q8+$L}jeiBgTWxkfDEPS_ zJ zul8q3%gr7n<8gr~|FM%ZF0zfz>=NIP_+isA*`1_gcD3G|vh~LCNNvaAZjonq#at=h z%IC1^P?@dQ1uZTcdmRH!Dc^i5&<`|vKGW{))D_p#9o4cW_niM$?4xW26S;!LvsiAf zz=L;M2Oo`w9+$)H&o5wKf-f9Cf}}cAUM^Li)f8H2`5LfRvA=oYyqS+Y3?Oj8A*l#m z)+h^Grk`GQwfkWI*!Aqewmr7hxHrd5e|E^Y`#=Ip%z!4c*C8!K=%)ti*L55U?+;8MFJNe~ZZ2{ZhfCEt zNV$sW({O&NdS)Jyi^}R9CB&CedNyg+;cAJs#!Ug-4Tfvu-@V6Kl~&&Xkk$TefhMKp zEb$q2C-?gK;Y^FfWkh|iz1DUFnGqk)2Gs*IAgXwkSKpcgv!wSEs(8N*QR9M5GJc|y zA$9-+*Jlwnn2pgWH>)1#fb&Q33jTmR-RsyE{d!YK15k(Ua$$mC*YR3zu&1}#aJt)< zb|Uu&=v7o`TVoa&KfF9(#+U1xPp#(5k#527VBTxD>eumaQQJr(uVu|G?gX7PTJpb!Xip=@EJN`P{N$vg4vbPFy-+j8QlHb2U-V`RYkGk_<<=1fn z{%oFo?M~qzRTp>Em%8=q9e#mjImd)<$YqauAL^qw@hQ87a<>v$IqP;?r+8{ccdTf^ z0^{Woe0Zn}YCf?vyM>5baVc@Z_tmZxxKRsE;u4}r&Qv48#Wjx@fpdl=>IU<=)H-#K za#Y_A8bFXshUTU4*&1^$RdRyQyDnYl-TbCe+QZ(mAfZr&f=$gESHofT zz2yfPSq$0AdC#W(Zif@Fnmp)}5p))Aq+!w`I7~tno=YAoP&Ya6=Nd(wl39zN{&a0{B%{J?SxMT0)YKfBsx4ufFd>n* zZ#Dn2ie9-ihEm6KR2zsyLf}=0C^V-2Ed4Pm$=0#+s((msyDUmMc6k}H(LI!e7l}$cxM)@|=G<9Pq<6*O zMxKxRBXWWvGrsH|!*fhD^Uf|;D-)d*^(u{?JtHAkTNBS?0|~y87*tXSBu4qMy>q0HJJWHCq+jPEYDAl?;j`er(R>HcSDECHrO-2`YUZD6A@ zsBe$eDH-n4<)*S2tmGJM!zJNW)~@os4*vB$N-(1_wAIB$So!glkS_@N3Sjn#%1<|B$tp``<&)a(@igG5rf*3rlbST`W8>9|lYAX1Lr)CgKa+cb z!Y7^UmV(Dj14UzUAN4L$IRYPn~Rg9_0}6$iZdE&4`EFcsW=x$V@iw9L-J>awwf2GHl&n1H5~!Zd0) zYl2ynMIvvtqAwkGul_wc$TzgdYM8||`~A~82;si_Ie7&J)TEhD+@^ymII~qiD6w1I zPA+sQ%CCQJ)4~{zbggWk7BUF^jB+77#Uv=)CHWOt`X~Ij3gw$9q!NWy0%ck?g1Ar1 z>o}KI-pMTb`*LK>o~*M%2+~I3MYHF04Xg)4wtDWLt1UO*VWTiy6UILO{>%#AowD1x z`viymm~W3>{Vu;+_8Nt%_OLqXQ5ap716>>sOh%i|^lAcM^#gu~{}dcm_eKZZJk1rK zEbDLa3xVG$mZCGh~XlE#rmU!_ITpYuw;fiuNCr{m%A-zw9eJ)jYU} zs`6SfHGT&BwL$^B{vT8dijndz$epd)_B#{8>NM)1f>d1rJl3=6wQdP5aKbRscUpi7 zC|8+%u3?eHwFV|XGtiVKo4wx?}1ac6+L7&Cia9Z#atET>WKllpa5>-+Y-hT58Wfbh)F=2w#jkb&0C-KUm| zJ3sg>&ax!Si3;^@(B&`d6zsp;WU=B&XaVpDpn??vCSbP1JyXg>UTXp+0$J&`Jo(k7 zZd_tf9-g67Py}L0fAP2Gp*sB(bU_H2JHtV=*{nd(fAddA+m~@AJVSSA`=!NNXb)g_ zU=TI%ker^6AoeBSSCkfN4u1+^4Nv$|KUH!EgWehITUjKwsADrge8G*n9X`?*_;?Xd73-W=1XLpv2vZ&|+i# zr_Ij_Qn}Y6TPpnQ8|F6>s^9&~HO9N=>8?Oa+^2#%gDTt_{hiw(AKDOMW-<9K$0%J| zj%$9eb+vQ2>%AZ6&IMf)!$)B^s8nR*vsq7a-4FItdPkvgzPuZL5lVfI%x6si;dQn< zc%`avi2T2`*4=UnY7b)>sm_G&jf>bm4ZHDt5q3)?F-2yF+-pZq24qF;-PC&7K0C)Y zdK^`Y+vYWK4~3NwVr2W}?Ii0hJOrj+#Gu3QIvVez+1V%_t#11@khf%$+1)-IY0Nr5 zz9M`7zR3%Fziicd#A%r)P#;4sip4%&)w&L8(A=m0_j^GT(_cw3ovbpT+G=6L-=fx<5lUIf#^=Y)gMB8@YGeL(!LOr0?kcji00P06g$fdu)VUFU#5f^CmJM z&w^&IYvtHeHoYnQtW6Rvwv1x2-}93lzIX)kyAOp9zmr~UavEKo8CkBjiyHfhy=_fF zUXy~}V)piPhZ=Mon{$Z*?`YOL^?m-~bh`W6hAF2p#0e{Jl@_!9U|F7vfTDim+05pd z$Ko|1WqzEUhX6i7z;<>T-lte@j^w`p`U^@&_T_)phsOt^)O7U8CATUtt5+1vUVHaP zffu^#=U@dN)8tC_7Tfh>>PpP+BgAVF)!hm=7M*^}!UewT@*fX2m#wtM#r&*Bc=*$c zto)oQGYj>#$}U4QDB+3A+|uyZsDAS8%@y3~&4!1Doid)k1x^f3z~*0GXaNS7WC^~_ z#Tde{>zxJU#d;!r`P~ScN23s2r~||mh|StJ4;kP3YGrS@*>=zpu8YfP(qz}0LRtL70oq2vp1)sOEic@PviEW}i96kZ zYv~V;Xyc}d*R4Db_HrJ10?cXn`<+_nV1?PbXT4CNH(XPfcg74hmFi`&L|E^zK8GV* z{ZZ;28g&AT-X`9TsQWC;_;m3{7M`$ulruf1nA(ULcfPZ+&{&EN?B@2|u<-JipTQR* z@kMPBOkykRoboDt#y(u0typ2PmO!(_B|hC!lmP$YA=iJ%hv<@l=71c$KTt?^hxzP~ z>_Xn_#LG6o&;nvnP`U&3GuU-_WOBImGJnMVD5mNCeS+YOn%3@deqenpu`jvScjnH{ zfC70q%fkuTOdW9R$55&~SaV{b*8_OI2Krde|L{5AZsj&ZgI9?>a_U{Aqb*$ojlbn2 zO>%Jm^>c6Y*Da;T;qwc;B+w(`_S1bJYj&n~0u&pgqje9cTZ;QDSWxz0icsC!7jC%? z>P6`r)SmbOfHnHD4RBNI2d~?+2gFFy94p$qt2eo;K#`(=p z4Swygo)L>KVV{baQKLP8+VUsR!pF|c@j3!S6tzN%}+MU_xK|iMPYg$ zmA=ZDxQB7Ii9L6TaXHp2`R9GRwVjsk>b;V*f9d*c0bQvuj2q47%u8-c@T|Pn{anYO zs>z{@2@pV=2;wfLiq&IzzWFd`#KCLnw3-_%Rx9&FKJv@&c)i0PIrGyu6OPIyhn!<& z(3Cv!Hzlp@s#(>p6e<5v-Hg>qst&6C%6}Eq3eqUj7wZSrPDcoxnCPmtF-ypsK3#PU zlIWwxu-@`Iq$|W$%DSv4L?XF(?YljI1zB#d_HNy$blSwGV2RE{rQdIRvoXl$&cojP z(r42OsMhSZ`>wU8*X+_Pc@w~o7AYn&!%J(q7D$qWJA@>1Z;1q49ufgnoNt#w{( zj$KJFCk><{H_%d`T`r0Fr8>7^{m^f?>FlY=53v>qRa$L4!j zO!Ag-c@(wPupk$eb_uWz;E=ZHjaX+J!;uWrM@h1d6Hae+pvA~q(6ayx{jZ?Xxog$X z7fp5|!1uZUo*yuQEyF>DT2--m3`Ga`PxlgOQRgIot*fd)ammw+3X4MWEW*ovJd>if;@dM4(}JyBNr4i82&*d5m9N)@2>t23I*e;Qpf#UR zt{YY~VbugKoJl_N0`t?#mx3CHE?jQq>f`XcHkN0$KPoJZRl9TnG<+A8`>BI=pj|wW zdwrO3v}cFz3Oet-LU%8{%PD8Psr+MFS%@-l{KP2dQ_z8H7FiW<+noWexwVDXZX`b+ zwzR1L77Oaprn1j!nUM#6bpoAOw={J}rQp*WGE$Jb?_GJBtC0OO?2^b+{P~?UFP+uk zVbj>4q{TK8qjlP!!SI*Ro86(!D>BgQoVH~1B9NPwQP`5RpFKl^H8`_w&EeTmy(C9vlFn> z3r-u_w2B=pd&@sqwN7zdz=u0+!s>tSPu!tbwQ-5YpWwLG#YwSV&fGv4Fe?8sn>Bp> z+|%~GnXH#frTaKvU_qrEW5l_2HL(ct58;O85eKF{{NI-5-LrfmGPzY>D1*m5_J>I{ zDMq{J^m}l&xmwXE5lcOJWbB|&jDYP2cSeU(*2EFnS%r}py%wRAG>)9fRod9R@EC^@ zV5v9C{#Atd5)cpA+a!cx<%MLLntJ@y*5ZNz|K7I`vxA+fPd;!+y@}S|FtVOvfs%qvs>Ce0sqPpLr7_9xq24|Z|r6gj*u5w{IQgosWF77= zb7au6<=Ll0HNASFA!V&;v78;sO@2A;tm^uvhBx;|OS3z?nM}CftbJrgiw|_f-tY05 zoMOw|e#@klc0~0zi?f5|lq>8WK6M>!)7ha)4F9!jvzNv_4#U|Onc??J@mL$DFL?|O zqny!hfW5{=E-;k$xAn!Se;VfC2#qy&=EfZe)9_&DWo$|34$p{8q&X3~hpc+;bjOEy z`Pu}RDc{Jy%P07|l)2vFukawgW1{nd<#4q&GG}-+ryrjqTp34kiB)1|r;f|t9BN$D zq-023ceaLPmBoFO12^7#QZb6Y$jk-RX^VM^#>%1Gn6Ag^ui>} z=6v!6xG{^SV9GK&tOA9?bh-cAy#t-Tp0_L1u;n-#fAsNwH7!NfIQ%<2iUMN@`*+xB zRbYTW_3?7_S4`OJ->`XGe3N>ESi{^>hx?i-fw0$j7k<&^)egZA&<}xjx1RNQ`!hPRve5^z*64S-2b!TmhWZM#qMqdR zeY5lzrB8P)S^_2-ij@4eK)WdLX+3BlL>d+-A%@FDGz_lAb#?!uLN5^}nQ~%`Ii| zHvM}RNG~BavaK(!TDu#yx#gcUP-un+?^Uy|?Ra&owwMB5)=vO~9V{qnAm=NQ&)*K& z`lc>w^mr`v3k20n^Dp%EitYGh?f5s&LZC|OKJ44y1hgh)wASd`>50rXYeY*`e9c9Ogd!Yw%TT2xK7>} zTOS=>jb6X;OaF{lU)YFGd)}}|?EGkBm9sJ^LrcWrceoIKz(eLqMS)HmdOFv??O%q&U{9FrC&+&@&P4KHb_zI`Lwr9P~}#e<5G6M z_tw)?ZhdRi>h5g%YVF-}f`|0s?9GL(H~51${j#@gc01vP&yG7*)dz+GDHO^j8$Rf8 z|4c?svUxH{=g~&d^(@R6teEu1Tgo9W{;P%bslO3N24ZiDXb-*P^u&50N;ns#t?ebb zrW#-nE1_>LEq*%63@^%U9&Bxtee{nusJ`Xzz9uQ~8IvCr)O~}(7imxV9|Bw5VBZ0G*adm&%1@j|OHUmep)_aoWF19$N3bh?TV| zsl{b&$2u~AdqjA`oVRUa6bBHHj}p%z>wjAOE|!Y*Jl21vSEBAl??Sgv8@c@L0ToE$ ze#mZMmb%yp*ad~X5$BaZN3oGBzaFeFn;O+RmB^i7v?jR)h}K zL%|Z`#7@DJ4#R2EhG;$^?MwS*Jc8RRuzrTdT=@313Im1f8S_5Pm*3pQ7U3cb`)z;n zOjI#F2fVg)7-*`7PtpboYlT}M+|d=$#N$L9y>|Ua6^lBfap!@$-|Xp6c_7pGmWNCD z?=IFkvPHjZ+oQhYE9})a3@q#;GX~2n&=dW2v*O6;U-6`V;z7Q}caNoeaQis&ayc6x zfVr?Xpv=dIU3=tpyxca&Vl7F>yKCkFP_{;elh#|fy^{JcQtq=k>K6g4fgr`xujg+i zwe`tOufbqipU7RxQnQkXi3k7J??<9OOYT~ZPz@`;Cy_PL-7cfN2AmleGgp`7IJVv2 zmDl6id9wYh7Jjg=j6nj=64$eZn8%ZugO#NPj9b zUmw6YiL&Ht7(Wdgw3l+EITT^FFEj)nC z;bI_*MVG8>`+W#{_?FgrPKymRmSLs9Ia7NuB3!M#QBHvSTTz&f@9@6{H>#d7$OqqA z%ET<^M-frRV2=gu-*uhv+)d*QrwiBUJa?cn;i=Vr1VRAt9C@ZZptqF-*)V2BIR8px zY4xRj?JuK*MzlXZ+|hgFe1Be6*TfgNezo6ncY}%D{r494o285Ze`3_=OO^IF|Dz(9 zjgQ`Suv|WB??V{Pnl9=ciQO@&)CR)GH0tY^XS3xFg7Syo0g?B_vPW)g)1j4k2zdk4 z&HlJc^;C9f^@1zPOjO_l%5c^9;+s%G# zu;QK#+g$S2e9l^xBdXUao^zq}D<6*LQHaTh*c(>!e}1iZbf0#7;RE1Q@P|#hdpt;^ zbtq7Wrr$gC-~tPit3e-%x>MR0OZ7h1g^Ox~!wah)b&7tY=Y&+t?)%>T{w)fo_FjA= z=-z!&o~)va|NmvX}< z*|HYQTtp|i2OyI>YWvj7wkP-a;s2dsDzD$4B;uG?$2+#E6nYHKhu=*Uf(+&hhCI%k zhUY(5i7m5N=j220Cp$la8%|CI|JB!CugT%7Ki6D8j~Ck7zJgVd^q0(Dx3O6q8ud_t zydX4%5v2JBnpb0;&P#j$gHZaLc^}J8huIEcL&>mV>uG-# zE%yQbvVYx&jr9DNoV_l8dG)fI1@Ox?-;l8}_?q46eiaJR<)^lWU9+o>mcOe@j!MJI zoN~q%rqP9|WaPase8#{{RKjE^S2RASKB-MXYpEi>=rxRarR2Nr_{MksnrF(bGu1uGZ|H{9>f?R?Hn&g-{M47yfNu4GCH;zVfM43dY_R+pZAzbZB`f{rNcUbhysYPFhj zHm#O3-GpwmH9Dp9P$Zvhp*F&VYBuys9D$;6QrLWcV=m6M>*;%m=0+EB=`V5xdIFvI z)(vJ<&Zj3%pVM1;eX>4GUn<3e`MV6KK40oR=CAHVQrN~>EjRS_G4Mt;FK}-2S-VGo zVd;T?F*fckIdiot<(nNbx=pI1kH-RvZfuUG8|OKS>|(3-H`5pXZ+FXWHg3OmyE9Q( zDdhH$9o@Xxp|q;u);&l14nTf5A!T6VC-C(v>CI4Sp)PCDz+37!{NdSihLyJqBJ)u& z8|~cY*0+^BXk0f%Uq4WMKVyiAzK4seup4puM5w_B75XoG4*Vf!hOnH=wABm_y+~5= zE>Apf9G`nLq$S;T1L7dTf!T%*<{Tu>+6}q-ZjB&Bb{)XKQdnfzN^;gsm{a$lsfZcM#f!s$n z=aTroe|M0?uy0wSW14GzDO5xc9*Q9-=XbQR)+-d-`4Es`G@mn7$h|&~Yi> zW2xo%$6d97vd-<^1UaM+$hoPeXWlw@oM9Qx&9_tW>LI;XH5L2tJMK5?gBs|iN5|*O z#G|&C8_ebL2)PtK9>a@HUp5Ql9(eEJY3c2LEZuEQ$L*Bg&R`zAYGjd0e!O&>XSqj6 z=8#4g$a#4_y~?DKRW49jyWeQ)x0SL-9pL}hYP4RSo7iZKoH{<#*eheNzr-?K*o62u zoWmWN1BDh=TyOIZ%L(lPboqtN@;M!R!(mHnTX%aG?Z)THyH4-~8($AW&T|5Pct5eo z*o!VoI(JpEdOWK1x`DPxubMw#HoqDQ*axOX2HwLW$n&p$1N`Cp#5u~0Gye+C5T6lr z(yukh_N{SqoJCRR*6JqyvTrf&bI9Liy0)`d*K6S31NU`%fj!#bbQ5g2C!$bKG`_Ga zaaXm_Z5A%MN>lB?mlm?c!+w!-UQ5`$UX~)evMWPP$^EUzq&o(ajgO-8deM}-zo0&I zFZa%?W=|JJwN50TNP>7(8N#4-K&Ln2!=|SS{uZB+@9p8^`3XaJ=Z}61M2)S1*Q8Hh zE`iV3d@k?P?R>6t_T4|&H%Kwp&Z86Cc_GAV<1WB3{{oa*LAsn>pIq#zbAN_*pERna zs_Am#9!A&Jm3;HU!?56>z-_P5Ay}7pk?gZx{YtvJKV4F`K0vMogbc;{vA=p4U-S@ zLGkeHM1Q$2%OHRC=--Zy{dTU``!ipIZSEV+WakgxWJqhQDd;b^+%V6%Ti;55mE$d=TUeLJ|mozVrVA+az2X062&D>FF+)^u;<*yCOUj^&?CMO&upp9BA z7MZtbd=j=iWma0}f#sDqRn5!witq8ZQG{=0)>v+pY=JNC+b)Pr()vxI@wSue7<1m< zHL3Y)QY(E2aFB8LwGDv2ILp}UclXsOmR~u(oJN}}R=J-AlTnYv2-@DNnSDArQ_`c1-z~N*k z;q=Z@YtiTOz}x)rdk_}phx@!YlJB`5uaRam7-R2i`EPQHCn_A|!$|sZodCPTUW|Jr zi{e$MT8?gPbsz|5y8pgo)Q@gytXk7HvIkhVrxcrYXACHr+4R8vCXjHcfq zhskfd`MtjEbhh4uHM}$H{WGz$lTz_-(07iRZF0wxu~#81$<2fs{JkEnnKP3S#R7bb znxcF3{3fs0b1Ep-YP<2vJ8i~9pG1M$AgugOrFZY^{$qX;UrC(e@_U%@iKR?!8zjTJKHGynT3k-=|4t~pAaeEm)Vtm)WzcVL~8tr$t zzVVZrsH1C-uLiY{J=W0Pyg#b|q`fk~PmzPqHS=VpHCcdUIxeAgp%cxBq2;aFWOK<5o|I=2<2`-e-&B}yUD#gHZj_$!vW1~Lv&-(Q zM9XVo)~JnoHvl*$!*&#S%MbLFCIv%?D3_T`rD1E^%MV<84sWq${x&&fEPx!bdi!|H zMoITnz4GXc31=EFQsu8TV?S?C{zTC+Q}dyi)*inTs10k)WQAtk@2-(~xg;n)ho2>0 zHMP1Sbk2%?eRf5E;hYs5HX}vb-)B;sLQMU#8#q<4t`42V*lf*$RAfc)1MKQrc-au> zba89`Fkruiy@_ZMHO9R8@c3#?BLL-$tfR8tWSi|ZkXOvxBq155k|KSX6MwL+wqhhl zan~~2)ZbUJ8{M$1Uj;Mh8kc0cMP{#aZjpkMWV76LcmL{G?oJ?&mQX4=*dHPyu;Z&F z<)A^_>owpP^RsSp11-m?PLdLRn)~gA-@=k}ZGdc{~SIglkl z-aKXqMs?!}xj@*rN|1M?6EhO76 z^ov^*Q@U3lKOvRZt;ZC8dA!?1%zOW8_uA!Z2iai`vRhC0#pkVm>S-QzD@Q-FQ(KVP z{2oWg)=1-6q2b3BbiypbnDbbKxl@IHD1d^mG@3XyLf)&vz-wJs_eEu*^oHX=t^-8X z2i(g?foVp(DB3IAk_Ogu{Rm(0IYl%Y=LX)?OXh*Krsz6=J9f==%k8K4yf$DuT5nA3 zVFeU5zi#KU{*}3R`8XNk)rWq1#f3qyvf10MTtc_xg%><0>X3IRzK!?IiPc|LOd>qR z#cJN?YR8OfD2R2*Y9($wQkChYZT1g7zdXWzKbjxu@xAxO?NbI3N9;C^w%c8l7Lrp* zmgECMQ{i%uJ>J~SvZiT&)NFzh=sYE}0IcT5jJ(#Df1!xXXXaKF;mc=Um|R8&=7lVz zVOC#&@g7n)N`1QKS?uV|^0lBAS32@Gjbz_@{}N!26KL=8+N+?Zj!+aG!A-~A~6Vl&pP8Z6_4!}DL>g280nWSZ;3Uk%|jxQjis5t%3ioN*B&zWU8@AJiiFR%S0s^}JJc`CFg=#&zWK z%#*E@nkk}ID$rfmcA7P=MpJLo4BOu4f#)EpGQ@P``C3BS|Iy=XNlIwaG?_yS-@KQX zb6G5GPBbMX#&ao*4hm1blvAMy!j~QAl&$OeT~K^Z3)GFe&HyW{g!9LSIUKi4$QHx76l;$=IARb8mnBJK;b=SMyv3A+fgFv~Wb3%;k>ED4Ubz5cv{0hR^ z8;BmLS_O*rtaMK1>f9LuoMxR@(a3iL1d0i^o4Wc}S41IKQ?} z>w9fj#G$==X2W-_P7tL_Ouio;MJ!Yg8Q9aX4IK2ybpjaMOu66s z%xDcKH5@V|pQpeNs^qn+kUbC>q-JW04)h1nqnk;CbFzDpS)1}pDNID@HC$>32Wkzh z0x{J6W$P0xI&=O3U|gN`Z6kgH%8h7~?0%myYY`}=?_pahL$*gso1h1y_)IDk9v*8@ z(nL&;zB#zYy;ZgmRgoV(bO4HE9^t$4kGJJ*M)bE_LT9vG6sX)vs3~1ff-TUnPBih3d{TuD> zfBPc|f#OoJq(Pr`IQL-(d3k+!6SJ{XH`$x~Q=%c8mUtmR}E+e?8O9pefzQ9Qj~}5drE6x_WnqgItpu4Q>Y` zQS5$^5r6b^uq?_FYW+FLcyR)H#-g!yo16*?vFdh!)CtJmz#Qh%$ivE_^Sq8nhyE2_ zbNsRiGN~g0U+(25?kQIEan@=jt6cXQSE{qMl4iRm&l^n-#3N%TsLfe>)EWO#9sjO% zM}4Uphh09LSJ5EE;%p1kQB0nar+I}`&b3Jf&-Ib|cK{+E#H>eVGiAl~!4nVF!eLy) zPEy-M@aN+6trXb-%c(*?r#euV>QYqJ#-R~7d_0CtuG9_d4;rzFKHMow7Yim=uK(z( zz|=^^Ob*gf^LAmNxI20@j5X@d^snz_%;tWEzABM>#(1SRr0SjX_9Q;5($X`nT}K(z zQSOFWc%Aj|gE{B8 zAuW%45Lk%b@M78{B*$?~oo@MA+`lOLhi7m<1{?jQ74{hhS6%?kaD}A~6l6ckw_*H6mECm475_UB?%_`rhU~4WpL!*Ua4g5F`|BOgJgoTBE@Aqt&9G$dhQ-#NzPB zX#Kws_D|Pwe|^JX0XIC&7OX#i6@E>~n=i8&-hZ41+rhY~)7EPMG_^p!Y;{mpcu^8w zXWZ!faa(FTZHD6F4xi-U)<%s{napPO;Nu)0(_uVG8#DnJ-Ar*XM!FTWf^MhP-TU-} z#rbt|mKzJdIfXxY@L?1c@>eStV|eUFH7T{RUCHt6~k!bZA}&7{*p9%_3X4S zQq19lZg1S^(*iVl>DI` z!KuNv+T>R@+^E#+tEGEI)4Dg$Rf1Yc^_Sz!>#}^@Su4!CV(~h^tETf}42hRcznh z^Nk%dS6o|BV%$<(d*JH_Zn8rQ|$`JEx7O*k)ssTIg#JS z55S_Pv?>l99-)H>88=B$GpEc4$iRIdf-a0L7{2rBh9k6AgJ@{;=YbS}Sd`l}C_4R} zcUM$I7L{6ZgwW%qJrv7PV^(HQY{`Fg(&^<}A0gF7dBT01K|#A{cjzt4cd&WO4geKlb^ z&7<`$%>L2~#7lOAI0xR*>yk`{CGqsa{dGYT#_}>;0ng`7>~B(c5$T9ri63)v!!ga{ z1&#pXThXv59cpX|-uoY-JuR5a{>7QcS86lAeOC2pz3UX$vPG&vMesj(_-#Zl)P?u*##$*9{lrS!^@dByKzc~H8{DvgTXK6cPN2j}DnmQs5E z+71WmhFM5;{a$+=R1@DjY(4E9!p?b|T5`BLC^zxqB+;wnfr?UBkKwa!Ummk2lj}6BXMWi=r(S`ate+Sfr&A!W z5`SHoU5Lep)ogw~1E3=7LP?u8xT7>_9gfX)Gdy@m{F7>#+LzK+~}J%cee zO1XLJMBA3~C;TC=!gcQYqA%gc%!{eo;KZkW&h!NC{2|W8Fue#dJ8x|}$Ei!^;JrQK z*toI$n+fx%>I3vgg=r5q{1GxqihJ%{XVh5LPBo*hs+?^iFzE!tVEG_|OW*4W(GopfduFQ@`pv zl?JEf8sB9w|5f7tvUZg*1suoaXTVjZcGT0VRm2bG%}Zy;b%@70aCu zR#+pf;KyRAfK%_!b9oAy;)U<{wRGEn8=vc3Blk>4Ea+!z>DX&eJb6jnBW-mkfwSiL z>rjC<&4(SpQ@$!ND4S+X-|HHU_p}!r&y|uf2iQeS_S$Ua+*7^%VJw(n?s+;RL zUt`)ZQ5=kb@xKWAFNcx3(PZk#Y9aToPGrNCEa@+rxf`mym(mk>5tL=eo8wt~2-Nj9E>~SYZu= z`UEZzvoc&>DRw*#VFTg6tV|bqrES?PInG6_kXAx-EvNY1tf`?K(dnVCKE%N$(rIZl@R@&k&iQ`4RRQZxp{1*X@RrtyX`=vtZk;$VeI4NG@v_ zz!p4g;CE#5Y>4!;QOb8$#eljz6r{2I0@wO-l~*~?C$`jc6DE1taXzqxUbXJ@ez{4$ z++lA344M|2uMaVpckyT{#Y|Ff)?y{;&@7d{Zt~C^If(f`m{B#{*@~lua%WHUArh`(firKeXjMXz;JE~jc zdVFl<%{ygU%1WX7*GcAK+gCKkXON)ZZ=y5s!qWNbWCYvnul%g-sJ?psAs~nAi;Gow zUj7}>=CPUP4sOG#rS&RI6;_^eKkf^KIg))P)??3m?bAlzyU`lI?D7zKqw)NP31k|F zgrI*5vYfj&XQ;m2sObsl)<|`#l~ew!QUhPy9tt_T&;$hS)VR+27?W+sNBHY2r=2{i zjjAj!3+p@n*EMU6FwPA*U{;9&@}x^XSYt+%)m9{)I(14hK`Xauy65^03anw@vGp4$ z+x1T6pgdv|jg{G$rBy6PMZ9!c=Er4tSIf?Eg{MF>Fx{yRvpo3S1eG*zH~+4@H(#~P^=&`YD~p1g zc1Ir|PD`z4^DVX*MX7?rf&k1cSFmL+4iw(`CA7QU=bjGUrFRpKkFt*RYfNNoQ#-Sp z)^^!HqBLkPFMCZaeO3&*K?LN`Od=T*gXO4L-g1Nf?fma9)-4d;Y(7!K<&O;t{Sw!H zc(1fo#EG#o+>RR!x@}(5AqYl-!__IaQ(4-%ZRL;pK0}XdT2-#K4+cq<**t$j+gfjb^^XfNov6*H3YKpftytc%1P}lHfNzXO5LbGa zVe;$}!LO`D;{>3y*Nu_ruTWvewjz_YWorQomc?d7!mc#rt*6@7!5Ztgs; zhbq+@Vs-^1qQC59D^wdKR=QwOE)8(t58zD@ao+{T>%{B*qW05wZT6VcAP|mbcW;&} zXBWB9KCD!WX#cglkcWXe(!qeADE%&4J_hU3A6~9p`iBYHl6pkAoIF8{Yun9rN%xlh zT$9isyqwQ6vR5(+uYRm)s6y<^aRo%Ym*G)(F6VVoDz&FT%zX!tfqx6N#SQGU zl-|c5$V)%vt&+P{=BRKD4>>n{2_~Iy37-%Eo>)PJtJ3I z(-RP|gqyxO0}4bY=ik*<3HZ@^!1$26puma&mxF^h&gqrBsV#oRSF1*oetE=B58*sn zNtL2KniwHWHE_!<@{)YMt|Zo6m9^HdiJb-{J}>HW?NSRRT<5fmEa44bg&q^L%a&fF z4T(GYy%<3$it9BH24R}|cCxFR1kk7pkQJc^XYwy^Y~SyizKgIVV$xTxz8BF-6GHxn zA!@B^O#yN=;})?fFQM`^8*>#0PSSr3VVZNzvh03%9ZusQ;0QFRn&V>u70ykPDF6MH zbA@$lbf75b>Ngp55oH`@O?&s8m+nfb{YT#1{q8SX6e1ZfTOeXz4r239X?Bls@c>HS z4gKA}|0qcu0)&o(L`2sc?*gc*etXoEOvscAO5tgN-_)CL`VGA^UmJRF4~Ht1ecl(E zP`JhYy*#rvT1yEzt&_Br%k689*xX-1u4jqfY@*BI!@Cf-LaFTBklz<_N)zsgnfbp( z`xJ<)158dYO4+T3(%||Q>a*O;MYu@+oK~$#)1_zfKELTJaG^L}wJFN(a+q;lWlh~6 znKq`pBDAQ@?DlOm;m_IiF~w%~*`LDfqW5lXPRIJg-W6T{Cmjw~Bh%|qg>E-5YO@Nm z#N#0ozdhO;(fPIVv8Sef9B%#e@#QX!wv`wj3R>c4RU0k(@xgOtPA;#?)7qiw;drNP zPIGYTtJ=jUleKD#e%Mz#>(i_8e7cO@x`mzlSU)HSIoB4~xIa3}8!6y7TK_;|s|&Mh zt%lu-rbwrA{I|%+_iWo;B|pNFZ>Kq1#ehNuKUcaj&oOL8m1BNWCJTo=+Qwd6`n10- z=n0|u&)~0o@`T1@+qE`p#Wfqdd6;=D2)IpLPO-Gz;z0eLgm!{V^2DOzmbzXnrnwnR|b~+@( zMx{1eLFV3CM(e`thrgfw!L~%(b4uon{t?XNuo@^0rlryfUCuV`}SY!-##OBU_j zXtJM#@DaeXa8*4I``{K#=#`%A$17Q8TzDe~x7D|*1n>LB7)Q*ZnD#jPejDRKH{xvnmgRg7 z#08bfJw*z$Q-04b^G8wz1701Jy03Q?3R*;a-{NpTXj~rOJH$Zfr#-;UKBpZFpn18k zc?ER^HOg7l=;WxbXxA5+vl`c0S-E1xj=_!<5jOn)*SzoZ(s1v0;{0j?N$;y=yJ4mm zj~r)Z2$<}($=($r3pQ&FpxW1-GoHk~dUiXijIH6H9N7AIKg0^=5*L&07 z*R92Xod9C-PMOO`=*_f3r3~J;O?t2@Ch)$*l7blZw3ypD2l8?!=E_gJGSEt*V;Mm! z<$gB&amA%c)mln}9YFa@O_eAoquQ8r%AH25Sf_DIV=`#X_c{VTn(ND;<`$B70zGo8 zZ82Fqm#f_jY!vtdTf9^z*RGAGRC$m_$Z7=4xf^y7&{+Z$-0Syw*PH9$abgF37@Rrp^3i;bfT>pOX&xPIg^df~vc4Hw)|bckn3GiOd&N(4}+gFUs9Txifq) zl3YVYu|KcI*4HlBXN{`e=xn$NTwxF7H~JL@&-T%)*5ap1j~eN#C$vW4`%;(c_VT07 zvFBB-VyrJit%$^ZStwVjssz+vYBJYuNZC zew8YaHzgH9P?;f36MxjdBE!u~Umvg9enmLvO^$nAy0{EoXKt5NwdfK| zb+bl$_!d%pCeVF=R}Rc9YirQ1n%nYia>$8Pf46>5TBG3dx^Q2u2NT6Ry;rjxt&Dd+ zmESVR6r@A52K=mQ=Dqor;AA8ZZAM+47Sq^!=8w99l|W||@5;jiDBa$^@}j26SubIc z7>m3}SwX*b?HJ#vixjD$9O!qYZDx7d9wqz$aYkMmDQYqpj%jLdU| z`!7qHKW>+K{(@4z4YIe%x1gU-F}lzab$mXrd0OmM_R)GJjixH%uO85emz>}EwE&AW zvyS>j?X3qAN6te|MP(GL77QTdi9aA8iW)J-P{uThy5=bV3sWQ;d$Y=R6(qF&N)P;jDD}IPY{yE>$$I^p2Q7?_QELl z@qX$o#^-yH=v_9=t5C-K`&*=)VoaQrY;|~Q=&#!*YVgM#X`Jsqwa2A#25%0hOvF@R z4#O=cQvUTFO5QYEsyW}`N&(%;e^DmReHtD-oHMJ zRy+2pc)TCN^=;YBTsG+O;_VLPN$CRrgY$@|2}>Ou>LT3ft={io{aHN8=(7b!IiX&Y z*X9{0t_u-S+i^L<<17AK_s}Iwdb6z4E8e2& zmJF9b89UCF!gXQ0Yrl6F;9|>byjq`TDpnEQR1f_@c2cP?2h+-Wt@_9IWCmj!IQX7c zojGRnM@SMNXOH{m2Bx!9KEFJU^Xrojy_jH4zcM74kLz^Zcr0nUqb=Bs_O9a}?d4xa z-+>)^{w=j49O*oYTJ}nCyM5BvTMI0^J`I4Lgf5IKWtbn?2BhD*B<+Cc{z9kS)s58$ zhsO){$SG7J*JLs@5Tf7wZtl4f2+^#bjK5~c6Tm3LHeLg7nQBCX`*dhjx0$u@)|R#J zYrOH}M?(oba#yOy;l|@S&E0e81Mqpglf-zDu(M?&w;@4wQ$8I|uryHki#_JKTyrof zFOl@-0B$m>WcoQ%K#A=t5od7<4_1MLCF_uB4rILoP@Y7-~5G(NQ zSur_o9?v>Fj@wCkiK4jp7;b0WdNv+U37+1H=>F|HzA|gYO|0o0X)84p4;gPv?e&^Ti0W-X zt)3c^_ZK-FeJn6xZP4TS#rjNj-VINUNe^N26@`h18HT}`r+7VsZSel(8WX41Z#<5I zG3XXvaPMD>g|>e`qBqN0d0D5iU#xpj2`@c=8?*>V#M#AbRGLKFfIF~oZZ$x1fh<{e zd+J;1NCV2R&1(3uyA#&mNu^eCin}LVY#Al!Xr_ZkbqxNN0yk08`L}fUPw~cFbU^G< z6hJ)n?wbh^NVfF2p!m^A)lL4=a8`IyemH&xE1$-{`3QJpm~siLJq>8G%BhkA!^QGE zE-!Uc!NTTbPLBPr_@@(hwu1oX1ih{2AmjOKTw=;NmD}W}W1Pc;P?%fi)3%Rpqhr*i zI^{MObTS~O`tCl1zDYnB9fpooYH|cp7{m@m?&{_8y^hg2nA1bu98W@{!n2&IB${^+N7`h_H^RoIkmdZy5WRu$ zZnDn#)2WNYRbGFcI+~EMM*L_< zTx*?kLh%77fYc1=Q8&Cm^IZNVi|YHZv*-;IJU9NZ&F}M11H(47<<`yos}B>F;mR*G zd++d+Dh$#VK3l&f!O0(DvUA~Y<)mD1fhn@mtaba-g7fWZ;nDwW@-&2S)YD&cd^s9d z=Ymu;1+wQi;X~kjx{JQE@6uvtv1=)))xii>tEJkM3)9@J@~W0CQ0T9|@J&9Q08F78 z=hUcyNjhA-nz$Ezvn|6s#sfd!uB6}NZ$3?HlN>P^F7KO+Kwjm;5?jZCMea#$P{DE) z+dC;q(GPdWdjI<^RvQ#ZOcA~LWH0qH^vH?=8;UTW$K%`)cil(gD5n**`4Y>p6Lu%j zan}U+MP`(##kPWd=x=KlQcNCD-|g(XTh{f#<>U8vX?OHXj9oR-BREmdG+(ktn`3gQ zHE{~~mUSiK8)kW*N!MAlEaeWpU`#_=0Lu-2x{bUx?q-b)X3N4l+qg6ltZTfd%AH)7 z0&%{dU<9e%VY&H|)9==N($d&gsxviS$B*a$z1aMP3xC|``m``0t+jj^(_5B*j#Blk z)Bu8f7(LntDg9RdF zMca$+db>*4&++iO{CND=+>*-T-d{iORD*yh&iwXW!{s%@5tH}|6zbu}tqzV&#YGqG zX19CZ{x0A_ubi8e!ql_nZ`Yvi%{)7Q_vXOoZ{40IF8I}Ve~%6yrOl~rJ-0$Bx%6*lm2ikV>JQ$GPd~DqOzvaHDn45Yc!pebiI)OP(g}NiMo92FY|)dh84D zvMYqg0^`)6OVUfXp%Q89%l@R-+d8$({I?o;Ids> zl+E-L*BE+hB4jHuEemM|g@j=I+@LZRM>ixNF0AFQ^B_;}O=xh;u7W>Z#qcwwWDM>C zN^BBfZ*w^^g;6W#BF|M{g*VR!!>6%1nxF`Z4x8^ykAd zu>rvEni6~Z`R$n7OMG1}6=I03z1GHSlolIBD1^*JSw%~I$_%>cqBwu66>Xfr=c061 z8F!G~{gIPay3a)uSjhB`@N{pW-U7q@^7X*FtyANuWDN+0Q`*O4mwQ2`xjdiu&#No- zr1GsKn>l9BpKj?UvA6ixsa02n_COw~T=Ui1!xRpyO?v&oysJ-hcMG-;>g_U_l5b?H z9=~EQ-#SIz-=()hjhj8&r_~R-;Vie|Z<)58$rD`va8JBvrFN{pIl-L2pSIpu0q~XB zBX2t+_lkuf`FA*3W{*&Bho8(ek9MPDiCV((7#x_@9j)ySTV_uZn>25S^U8*kgxWdt z-ZxgqccQWAtP_U49-Zr@1WBIQJ_*Dvr#%oMrNfdHLnUnarsW1O=kJcjtIs@Vp|V&W zp64&B>j8G9YBH=N?G^a|$};>QKe)J>H_#fJQTyWUMbED5BXs)Gt+TSehLsI%S+6+E z-b@!2^y3*VmIj^+e)*QKmoBgfM0+X~%iND?&i566Jih%oG}u++0iD6^*&P7~^o*ND zN-I{c=MZdBt}X19CUBy*uz{s!03puqVzh?WXRYdRc4{KPjmry$e z7-f&y=pHm7UZb)9es-sHjM1ZQ_#?Y1Dt2g12QHkR%hx~aNyasIY%;07UA{KzaOFui8ZB#~D1#*V$S zNmLEzB6tESRklEU*4X09AztfJua&1yY(53)MKK$AO>rUS8iNhoey~ZbJ%|n-W@l2r zIIak4_Vwz&^Dud2TbEq-J(xUMa2o)hvM!$=CyX0#_H&zGj`rN?=@cfTg}m=*uUeLz z^Sfhs-NVwnLG~B7o;ON;wmtXn=LkN1?tvHf$~-yQiAP<)n%BWAeQ&#P-a(%Lvypxc znx@;&bt_nn1~ND2z3CUzNI#ykDn!@d`CRGMD>qpBfy*NoCz|RAEXGkN4!hqKQ_upK zTbjD?R%NMKiPw&W3HkI#oWrD}`|kVqkc{k~oW9r_S`%88uc!b zdgj~QdR}N1AWUN@zHoO9kYzKUW42i|g2m49fXOQtp*@1HuTHD$qSoJDDy4TJRp_zP zXlHK|lPCbicx#zy856Q(xR^4INeb^C+V@r{WH>B{42-2%EBXh%B=(qBDl+c>`)_1ojoH#qh$01Ln^Q%93^sF>OJ zjz}Lpe^`U;)S?u5gfz*9#o5cz$l8L3l?iiGFS$Myw&M6E$ZxpCJZ+>L3u?xQi-qDc|2$kEKK=wO zGa+j);ViVBLH+9LziE8NAwOYLXn+Gw4w_i`<(9_m_&Yd)Hcro1XFUTM6egF~c`|^o zJa!mN#WvkpP5BA*l>rAq1hzMlx9z2IxVA^r8aMpiXHY@Vu+;&7vA$?U)H-3@(sdGa zTmF?g)#(Bw-)L)CE(H>8<*PqipJ&{_R>xeS@jPw3geRoj!0rkG0{2TgjXeL__$8sR zYg^rl{+xj_ClyZNo(o7Vo56=i2z=Ru5Hezn4$2G^Qk4zFdR>jzC}8Luk{wlAd6$3H z3TlpJ5Ty`j@P&SCOol9&zH7k^v^|F|b-RR4U0X4SW&4smhS?JluWvm}@i|-jrMoqk z6ED%KJbffE;4|`0mYlMgw@gar$$=@?ymObjdl=-FFO!Tc#4+qUE{lgq)PPIhX(ALn z`}?0aKD6iAiD!r->?#=NerNW*pC;R2QF^Ya_r6|4+Y^+8*jZ{yEe94U=w*7|)Xq2G zi(3VHP97(m-H-c4)0eQ~XS$j9_{%QaOjNerWj`+TFZHDHoxb->T@TK58S8M;S=?im z-xwH0O;#_&@Wz_2?_0PQQQvGm7Mldn&wG2a&!WNO(0&PbV}K{HVMbq=pRZy$i~x;+EU9(}>%>KupCe<=wb+tW<&-5vpK>0}V;1aNNDG^3~l2 zVj8yQ1zI+9?=Kw-vO*HQ0`9K1aclI+1kwE8|FG3+d$aV$)SWi7_3GqS*`sf{Uqx13 z^scB^`8j-IVM+hJR5hB`%fbpyOL$%J6?{#fgyg%U{TaXek7ViIuO=pa$Uy7NVI0;i zEgn@*i3FUei1_NhfXg?y}H|(=HKw&jT6?m!@*sd z%A~c?T2c3T`27T&c4ez31iS8SUFTM5NDh%&nsFh!{8g=FwMwydvrg)O9-QtqLyiEv z_E!4SHDCI6`+BB0-&oj7DG3#6wW5#3&AT0c^RTb9iNP1>wd8krZIUgFmVbfQ=?B8j z%gsz>S}~O-imWqDvgdwkPfEHh)207j_D(wB-5>^?xMio|aF$+w+_bgv(asissLx-s zy$>!L$(`c+5GGg8p$RcR`==`2DvK`zaeP8-7QFEh-klmOl(+sDQqEe}bwgwcka@jZ z^C85YLv66g&0gBtc$vkfJA>GjEekG^(^ZB|e79H~x94Es7v+dQ!?SNI5aq>-S>*2G zk(C^-7=)OB!*4{5#;Okm>7tspf1hSlbGZH~e&+K9g&PeAi?U+`=Vl4*2|8;EBMrk^ zC~bnG5VAtxgB?`6Z7!W56d0+2s6!qB^onvR3M0~;`qZl`aP5_P4BVMuU0xcKiD~zl z9sT;OI>zs^JeoGDR_s=#kV}}p`e_I>89J?6%^xpkvuNgVPMG%1E1zT_TIk@G9q9OY zU#~8Y%IIFV^qfyY)M8u9l91?;bEDT2HW_p2UN4AifpK;x04XG|QD%{W>TqdRcRh^k z@9_(lNiSbvI~Wbzh1Gesp%c4JD2p^p?V;sZFzfS&LFamP=<@jet^P`$DqQ-cz$_Ni zy@u_t#f=^&rB&KU?P_o~$Xrg+7~Cow4;bSfR4vOh>gt&`K=BMw_^K!{4BAL`Q2 z>FbqU>4Se)e^dlwQW~B#dC61t+Nz#j^YcWL>i}TVN z7$fIgVozT0q^p(3zJq+QBeLJ!{4_jea<|W__v^zdXXCoh?s0PyAX!<;9>%#6ZNfNf z^m{J9xnS7>y&K8bIA#!^#~skZwS1nL1*Ob7s-8PxAF7#Obi5VPl~zl|`=u%5ex;#{ zAJfp0t=?IKJ?^92*}o?swg?TZd1ua%>)CHg1*so6B_grEDCPKGCIZ{j+1dPheR#*Z z=?bD(YQ4OKk|(F@3I4_E=tzu=cG9uDLV@E#!F%Dn++(iTYt~+lo+Xrd;ZGu-31E20 z)naARd~YDYuQz$-AIdF$neO9ULDp}ppM_*DsFdy}eJZ_kZ;=8_$ESP)svNq#z9zr= zm7F!2cTmlPZey9{d*%sI7xkp7mbyEZ(k4l@&-bO;D7Kox;kbr8O|emS@|((jvO$C5 zbU+;|xl#n4N8pXeB}MX|=f&3(q|UlHv8JAPPbT?fQj~tsh)>m9dC*)W3cya(=3A;` zILI^H3~nhUfN@iI2pY|<7tOLTE~*1}^fk5plo=n1Z*^VYtraabI%xzTbNfQd0wg>fC zr#KC-^Wp&%l<%H>p0B0aeW4lUx(MXK_ET8E6!jWrjZT+fl}mNKl;@eOb|B8C_%>ER z602`^5NZ*LJ@KqXUDAK7o0|RUpu&viTSZFTz~su%w%cMA8v(E9a!X2b9nqBY3dC({ zwrG0-x+y$f^!adAIq*cO2um%MulL$0uX7Q_AIZB3XkESDPb^*Tm(snN_ju&%(qQRH zoM*JT`qwSg{B5)ietv$`54lB8)eI_r+S*bo(Scp*w`(XHWNEc(Y&V_RvFE4+lVLO+ zJ$U{G17pXftMQ$i)hqg=<5c74CbQm}=uOBmx8=FE6^oLWPQYaoGNY;)WUqDGtrN78 zhqw)cV?PfS0Qw~lvN}K}Lm+P|sG~SH(iVW|ZVlynu%SM5j-N?aWCe*bL$a2i*XiSL z!K@V?z6227osns;vC>3Xs9lY=RGk|#tM zX5UVAd7pr|)$KPc6Lmmh2yt(*axvr}X1FqJe_JH$#|MFSM$hcUmuG8(r;{rXG#k!* zqzvZK6skUU@tNm=*<}h%dp#I}(e6Dwo^M!XMvsEuu8L(_r<2NR0j~3>==7B4=~gCwgSfpL=Uq^!=E3~gmFE)-QUq;& zJ%RziON1@eC!1Mi&BvhcuSFQa@X@axxT2;k79Jc3`hDnRmaZ`8yF~?!y2zQUnudlx z#Lj9{ydTa&4BFxIdb@aJq2D(b36ofXae-KiYV9Du$!$rhV#r$UubLCUoNLmQ8W}mm zJN_Q`X?|FV`{OvD@>ob@4o|dyKIffFJ0kL+_VRXbpMj9deE(;)JF`}MF#Xm0@J+^a zvNHr~nZoagj|~flDWKY|Dxykm8=~8MA49Z({Plw-d&)0tGVCoSQhr=l# zYh;d=KY38*r8bnt!u6Go?R-VMCySbXX#Dsq%=!id8}oxqTMD7uOkrynGC(#I%IO?kj6Om(@CwaUL?Y;dEgB_>_U|s zw?5}qP@7<e-Tjip&fxGT%oz)PT%XD zK`r_!7d~sbi0@#Sc3Nh8eEA$5lqMN`i;(q<{;GBY`h8@u_u6otTyI$WnP!_^x8SGG*d5b8D%#V=32HN+Q z3{5=O157((6>Oamd#C&ge6R;|UpbWCO=NWASTWp#_zQD#2{0Nz=83@#f-j+4;Es-6 zx9M^^ju+ou_`GM(QyAyq&K%znxS*`sN~;2bKMjE7tWBD>}^4b=J}P z%>v56+2mkJG?3+`@!mi9o;Bn+8|0IMigGYcs}}Y^Yy1FHW&8QnT9rGvCVim&*5t)7 zs*8`IO!RG)=9-IZ0IJqDI-~0+_qFv6UtVfwceS6)@(rz&Uo3*-&J496-dXC>vyZOJ6W8$X>h-vhPp<(O*C`3pPP1kiQEPq zQ|D4ad}W8mTEY-M!gGu6$I^C$d=A3J$L~yrKmggxpfd4bJwE`}bgge`BFvPmVw63K z*X4|5&t(`1-5|`PH?5lVJLXyceO!NORbYzq zPr2$|vvXbw!EilJi~;Hmn(KMs8w*|fg04?|RLQrHunx{xt4&VWov7x!T&s+){TzE?>BZRl}aan*PwEBM(|GaHlmrm?(^m!=+R5E;12$JAmv$ zt{Ve2jL9(doS+^kq1?_aW2lVE!eGRI=G{6un-{`Fo_9-mZMz1FizF~%f6jF6GhKN% ztMRT5Ce~`1lnPaGFOK^8hHO(Mf})71f%zg%y{ky)klbPal8vzX+{3yuyq6EUX=oQj zB?pRhQ&qrxfbC`Nal}4;RYiQc3zZ4mQ5yLzSqUKO>9^tz;_;OJx@W-catQs|IU|1Z zTs}{S+aRZi;<{n9VfQ+kmL7Dj_FJ@q0n^)@@V)p_meAp;ruMkBI>-wm3|8v)`m>{1 z`T24JNN1aD#55t_*{1%O^6PtLI0IYkAZm3+O^hanZ>5FzR_$gX3fKydK+Gu4p(=4-a3l@ z=o0jY#iWg2C+x$noNvuZ>u_*UhQd98fPP3UXM1_~x8+7Ja19KzzGy8w%RNG_Ki(0Y zV+np_z#T%|zW&PNEuThnoddt4_mF$QUAm)ZE17r`?sQhT_mZIoJW-NwX$m1EU}R4X z{_JoEc`X!1J#9>y<(!TOP?*_%5lXEzH z7a+1lE7gau?(9c_R$6Ab43JK?yuS}V)ZTad*K#!|)G1+q2Q| zj<%3Ob@o`M!WyJGqg|3I3h1KG*vI#y|Bf@zVVe^*U!9IZP+e%*DJ?pAkEsR-P|jew zP3{YidqWzTJ1%ffbal};O$YH-qe2-NVc_O~&{4K37FhkQDa_QXf9>UE07#2tHZwoa z)1|p~*^0F-Pa)D;tPNBw7&ZIsdhi7SG1r69rb+EisPS29g`tt=Unc(Co&bY6rUUL+ zL#_jM4l^a`nSt@&rTXKR^-Qnn$`P|YgoC{sG)&N1=+d8**W&Ft2)EXk-*jHBX59N! zvoYF(RXSN2WXU1|VXDoQ@ydFiQ3p|xgKlkFIk|a5cE)XZuEJAky`AQJS!vaUX*{`g zyNUR;$Z(e(mY28P6=}(R4{b_cFx2h=PobUK+X2gU2aElDKdM^2>Eo9t&;1P49ac5z zPORkBx;87Ix8bSwsyk_iPvG|Kg>en<4=Is8ZO=SbDf#=}>Z>S5tw&yeX?F8!-ynBj zJln}({npP45F1)d3R@L+6kZ{%mWLrX!K=V??e<~*OV(kD&TjS#^wyP{a7rjVM*Fr~A?=!}y~{nXg5&q|P0= zcK3pzsSRdY?x_oy)Vrd_VT(;Kfk}Ls$v#c!imrb-;1pB}?%`7kqvg`-LuZs9N|{fG zKY-o87#l3~mFnm^$;@e#4bw|6dh`PpS9oFxz;(*6!EuXh^Q{4b+#o+gC-<+q{J6;l z=W>>D7nFhGZ!XKK;4Oj|f4nZYFdzA){Er^gv~`asrl0F(#J~(zC`0l__5$u_OgS17 zyj){SJ42;^2OrH7%ieO|ar++E;_qs$B#p6?vFfEF{(h*mKS5gVyT}_ZxvrmsV}`sL zd#ndco80eu`B2F8(0Ie|1ULGgViQ$n?qn7_a{P!a`h$mGN{!j-S2q1zC0s_BK|@%% z%BmQ`u;D0$yvO&HzPwsugtJ&_iu78jJfd2CXCU~Jb)OW+x^t@i(2x*7v(M58lcd2bx z@wROdSB5~kW#tAw)`W3A!Nr=6&5BZ&zSF?%aW>L4s4CX;fmH{=+d}J*>N<93L&$Uw z5la-$XW^pKuVJMn2qGgH`+{`NT3h}2<)w{)G>1}8IX`Z@ZHWxFHGTh)PQh8XJ#6Hk zm(4|0g_FPQcAv_2;z)Lq8DFV+20GXd2$g6D^<3Xx86&YYS2CdDqTXes1q?xr?4sAM z)qKv3NU#Ds8o$=|{?z_V9)9*dUfeg%E+$@vmS0Ekz0WzY6JPejjrF=;juWB`Lw7s< z7SRCt<<42vKv(tGupLq-R2eoJ!=xhVMSG#lxaeh?mVQu#R4!#$5q<+A-gYe3z zkixmQ*yoV6H69i2n;=IVB-{8tcGld78YcYShWQ~RWzKraMRo7s^An!z^UxjS$Mfj+ zUL=kDOf}~NrO)M=*;Cq(Ac|kAZh1c64MuDw%BaUW8qi#q-wBf~6sW%k@hN`&b7Ptw zrawP|O=8B24Xz5f2=*rT*2tl0+pm)~hv_wp*H5gb9V(9t+O!D?nJ8fKVc=%wiew5+ zd-H4zeD>31hIo8ah?42|FkIrsu{@9_NnrGX9omDqSg856hO%g`2j^PSJ&TX_pSfO3 z{mho5RoV(`YyX=nn`eT|Ho~x*46IbL2~XOB#u>SUDpalPSuoqWmR#)C@X+3pWJazZ zO|3MVyN{U#=9BCU`pTY81p8+DT{_az>#9^6eWasqMiQp^AQ~MPr}u@FRoI>|p$sQA zc6O%JmMLfYX${yID0I}88}b7n2<;7ixB!OD`3A^tCM|k-NTIN^*Ha~dPru(%&r@Go zi+!UOm4#5Ze?!L9JvmRS&wu;BMp#VLEaCvxcJ7t3&l6biqk#c_?R-`j*V#Lxrfpfj z5|O12-3C=>Ke1Ma6yLO6k7G|*>t#`_O;6i-Ic(2}AaSy96M*1OXV z!gdOob4f~)L{84T)jKd7531wNK81$T3x@OD6IF<5yV}~>?v=};8@(q!KtoHG4$Ub% z`*r6xSrzHBu>_&HT)0 zaY?m8#5M=Q%5DkzNXLLC`W$ri-)=@$kIVX;#fozkiRu#VJ#nuQxNad06iTlaZ@LDU z;^sS`(9_H*!Y#HM)NaRDz1NKT(=scEesfzF>}ugy7Q36q3cfZ^%ZLM8=ilL(9UUgI zy{wf!mB~>-Th-Z5?tqz+ysFl1iC94;j~-?j6^0*`^D}ZnhZ+=Um|U5Ml{%-}pz|Mh zpSP=^)(-ZKO7wFXw6DFw5fVqbo@>5EhLppdae`g-tN~HqUjSLC3o85dBH&WW1nVf5 z{PXv#7v-I_1bCU7iJ8LEzQ`U_7vq|^*l-v>q+o!jwToi%&TqulUZpM`a1EG<@VA9+ zZaxS)_P2fF$ObCBF|9m#Kr_))xgycgiy>XDfb+Qa+s`M@P6-wQ6C}t|Cn{L1`dj$) zo6ek9C%>>wcU!YX{SL$ntg!5>cf2ZeXv@wQKZ|?lQ@gB;N)O_I(n50Gh1T%1u_N?4 z`es_^n%%pu$F=#U*Z(|L0|;5*#wsLIgN1`o$yFC9mew@d< z*-D$>qdOP%a#}oPZ)*L?&DUY8{HvwaQOAAxbAwt$l<06HkV%8u&=e~EfTG`A2yt)4 z3C#ND+}aAc&mH#2%%j4V4vXsZyB|Z4Sboj##*3L3;$?MlMVN6#TdNnPKPnG|-1Ad0 zxX;w+L((D-`Lt?xfLZFB$QiHcQT>fGBO0OwS#zusuW+1h4*N>_(?XcRrcp)LQrSI& zyrIq9lI6CuWzWm<`_tg$;+^)_DOeysO_Dr%$4muUm0|uV6_k%IOan20#>N?sm2<&L z;wo!Atai%QDW~kCT4VCd5d8F^zTvdwx1GtkQFVZnI6JO>TI1BC1dGnD>&tUgNJrSn zo2I?DEpWg4VQf|XvsZo|wcWb4sEm4p=MfnjYV4KWs6U z!h$+o7!(tDPSng%XB&NYT>5Cjlg>QXIQk9|W<$NLc7`H}LjJjBugcLe?C0VwGkBpi z(KJuH4W=JndQ&2E!nv|EEcljI(iP>`%|*QzP8eMm6cLw`T9tZ9cF%*mG;d`I{Xw{D z(lWhaJ7{&}XBO9-=Q}Oes`She*!JUaVxk>-P|AJ1dDxWJ)=&VO3)sRse33{BP{Jd5 zvh^{>lLlb*-!TVlTXY68V&gTGe#3I*x8s|>_P9=DJiVUpmN-S(v=QC1LAyU3_ulAk zuHf|G-sEwiG79m-pt*mo1%qH=SVx83?VIkElJij$0?+dTKlKfI-MkLvTC&x=_Q;Ar7Ck53EAP z`<$PB1bX2rZZYw@{MyWMY&h|;JG?a{L=c9UOb)?FMnY!ChASg7*r z9Dw1XF_22ePvm(i^#}tZ$lsAW8PofYKE~5!1<^&P(7RE@ti+C%ZOAvdCM;=uoo;68 z!R~cT5_p?uu6r&!n9G;23~7UW+^T@EkJNS<1YE@V1(6d$uCm>?V-rVaU*p|R4!dR@ zmua%ye6FKjA+zd@vD#k6HZ?ynkB#fPIV;<2zqwz&p&s*K_jJkaDd7?(72R5HM8U9R zN@JWV1j%7^BRo^mY!SVZ>6iyuDy%;U6D5m!cu0%u&6$P~`d4hUZiKqG9?1;=6Z(%2srD!x~>y@1incFrt7M^S6vgO*e_T{;%l8HeBU+Q;}Wgqs{ zhuyfj|85w)Gb`BC{h1kG{2j4P>7xDHHeh1W*`*Vrpj_u|`?As&$g!e5deiV*)*h4jZP9>Trn2?Tc{TF3g-Ip9H3nsC zg*N(+Q!_`kDYSHYN?vtb2Cd*NFS&^Lw8yso!UiRo{#=U7=0xOf^8tmmx;=*?#k`kq zJ{oW%zb{(=s8sATJ{m5mZ;NWL2jfaFDFd$gJmvLa1F!kS1jCV0Z-Ji=)qOj&DlnB? zt7yWPASHFQzq}|Q6~3-bV)o<8h4-&gELziU?(A*Z+Pwjr5mvYhIsBfK)G3W;V0llnIEJo1eyphE=YB$-l>Cj9-!R?Kgr{x9D#9$|B4j z(~r6&lXeLD3r-j z6NO~saJfRaGp*J~I}-AN2kf&nj%!%gU-eMf3U2PjFjdOO&9UcBK{k15z=R*pF&@ye z`Ii&tC&p5k=7QApz4~&k)qS!;$^E@nZuB9|YPCmQYDy2skBbpl=IeZ~tgTyg(uRnJ z2S`bQi~*=dvEWoLgLouEqt(qVBU_Kz3%tfd}`7Ve}Zz(u_ z!ujL|J@Pf2cBW8B6O_>Kn+4rUzvgq1{n7_|!*&;_WF2jI>|V|9G0h58EOc+`E@uGd z@}ggix#XPtKW|W;7T^#11cy7awxr#Bylt`-c)-e?;`{>l{_Dg$`fJOer`U^TuTsBs zTxR7>F@9emiOC^qW*&S>~lqsQRbSpo)q}L}$74DMr2fv!vY(}9P{WUWjac5yuN9`Nm z4hUHRFQR$*lryoZ+Wa!cbA@_kv}WJl5*-!c&MaguIV^$R%~P0aChv~^==mp=cwxkw zNxcz48NsZtv(7LB)v0lTjc|VVZI5%=62$;pYI_47>#aDrP99`2bz=dQeW_(kP-X!H)5vBof_;P@J!F&$@ zi?21@$jwHtJ?%21`a> zk^*Q0Cb;^~iSf-`picH#z}0ObCuM0n770h?O4)Y~!c}>>^kJtn>vEH22Y6vNA>-FN zdZu~cfW#`xw^_&YS&#_$jc5ttlzSc~EmC zvcOFA{iJtKdqpBdBw&=1$ifhB2_zbM6zR4aYpJmz9)98GL(ATtByO~2f79?5zKBb< z2Gh|S?Y-KWm|yhw)Fo4gZ0eQTJ+nl< z$Tp`;2zE6PCA8(?dv4yczf`&UUFVCd^8p(l!rXkF#o^gMumV_g1}sG1guBth`i3Q> zam{VZttec7p~1v@An{IfdD)Mv0Rvh)sX@V*3gn94U(0ng zcGi%p5mdIPJPHe4*o+*w!{KFF9mryvjVf_>73HZ+(s^9vmOObU`Lkzf=JzZgMd{7& zu3vS$H?DFuQn+%jF=1KhDY<|@iM#zMn?auLl-FK^%uM$_WY|UH zt=MQ=9fT(uSz^J~04g{hXS!8lP+V?YEu!gSVaEz6mOb`at0msFJH@Nh9x8}~>-0Ir zVZ#kQvU%ymA^AkKH$fV56?K$MwZ2;HL9c5Lj+e=-EFbbq;oGR=K?QX`MVH(RF|b$p zGE?b8rU{jUn402qaazC1@Mi-gHw7vjDu$)Zujh-+YXcNS($_nUTUNyP(tSf9uKV&Z z#yPioA+CdczCX;t#9PsHNDf^PBVizBB*sy>svVJ{s^|?mcto z&YU^t{LXJ??w4(^IzPnnrM2{&w{`Pt2Syk?=<*5vJbTr60qd9C1^ZD>CHxQ^aEJY8 z>>b>&#~Uz9hGWv^H2$pdaqu}I^Axx-%)U3q7dN`Zo>-((d{|oB@3=rt5DReQ*`XKk zC5+IdpCpGE?Rp76_S@{?yhM3;#EsDRN!w2SRk@$mgVRfv)#L&tIU$lcwLC(FBTY&+ z^MJ_ATMuU3B{+~1iUslt*Ru6A#A9iKoY%Q19+S_AJ#C+{KH%JM?ZoocGvc?f zT|cnRD?#Utk_$Ae z%2)K<>Okw7q;O)+;Q$Qea^u4Ww;PfDlfPb6X=NN0lTtr0V#uwfidbRnIEG@+T(Ea~ ze(j{S|0ni>3^{={Jg0|xVNG~i6^&n1@E|^`B2`@*-Tn_e7r)r6KANLW zM4SlsQ1#=%@@8((ej-A<)xMIFt`R;rj#&)AYo8BNE@6d?%lQU&;>vO(;)Ed44hyVx z@i(^rtXz=q3VD{jAY)c1l@(G-bBYL1mc%`5lmDI|H*|gQIRQLQ6*6PS?tO`a$e0_b z4fjs4ur4nCdz7(WihiAl(fa2{*V34eXyIuXh|Cv;B*yPL6?u~>wsawA5fDiYQ8oNwx79XCqR zh`$3vFX#zmXs&uxH0^7B8$xc3<|*r& z&kON_zBEbbM;`g>Lhczcuj5A3IQl-`Q%O!Smxze(cUc+p57&h%S;vX8eXZK!$DC`p z)Db86tbR++s%LqNe3Ch;PWtNuxu8<^AywnV^{`mEAvr}1M6!o^UR}z6W2YRcUn`J* z)nnw|8{h&~;QJwnN?ac_p0Xcdz5dOId{^+>Zm#(E zsGJ3`S@Dp3Vpf&@=An8ep9BNert62U3;s?+em`vfJt~J2uuyKqSkRJsNlr{f|MHMq zKSE9j66}xcI~?h#ADM4sEEE@DB(0cNRg${m_pJB1f;EkMD1OtiUEII?xth^Xj8tjhNT<>STcg+xm-xa~K0Rm7$|PK--uI93%FlE>r0Lb(Sl zN^`wUJK+QG@t&5yr-h!keIhGluhX`7Nqe0;Fa~}y&yA6B2m`{>jiZoPPDGBPuq9kw%{xhUceiz>l-^{x9USlY@|2ikg(Q2 z#S4wyIA#=T6JOfKxum_u9An6DoPq_$Mjc|;HC|!?^+?1}*HvG>AJ=VuUjPZ5jGjpL zEs09lM)pwDHYqH09+x=L3mH#hh%)_XD<$sKBbhsXEPO`bcLU!GMi4TLaJwhf!~AU5 zzp1r9cOYK$L2^pQlsE!|E;zsf)q|Lge-8x<^_x5Nf@3q1O%X}ohn#>O=wvL?_T6ei zPQ+NiKN(jfTI+=oX-_OeYkVD(zykXH)6XZ#DdLbyS{_=QKEZE25s$P@pPHtB@3wx} zF)=RAP%^g#8$9K_LapCVa#w6-`@T|;;5vc7^@*{FR}ID#BZo1TH>gj)vDpj$h);cD zANGY6)GIReA>L21ecD%bVU+6k%wNT>9~RU{nM0z98;r6q{oSiyuYNKXVN|<3#X7?| zHb7;R2hspiQ(=kCuy@-UUx^HRKF(%D!asA`=}mb zlCxgx()R2Z%4$BKUG5YVx?quNRD1I!c+vmN#iHx#0c%2iHJljbne<`bZW36;+*r0b zh<%pSgDEArbpKoP$zUPh;9*?phcX~6F@}mo2@b<7OE3(_R-IM#IbNVH{re{PL0@8- z(~{>wMQsmm)cJ_nIerh@CFb-(@JMmsH+F^1BTjhlhkjs8>MN6ZPDotSc^~z#Ufv6L zxFaBkD63X$&+5bz+Am&|-{V-9Jo^}lPbp?ye1Lx?I3~KM?qSq zex-3u+r;0~VV^!exO}s$z?e8oBy)J2vbPUl%g~2XOwu@qac%p4EIthVC?C5nyW78W z`H;*!U2DsbDEGAlpBC$Mv7fN8gd2!=x`z@J+SHFNlM)ZblX_gngGbk#DeUJ~*{XbK zpZB>QlS9Gxu^N&7I81^IzU@&t%aJ~uu=dw}O-JJ=+1~X%Yz{fn6$|&@^Nr1}F8+uw zVt+2n>+1kOmr*CvhqhMnKCYMcld)wST9My!#p?#^$1zH%!~W0udLFySbnF?^adb?_ z*)biCGd*t8(*S6CddCjP9Xn=cA!lb779bZE78fBG7Y`nUJa}+r1#)F&bro`T_569r z^XD&Jf|NT-Gzn!KK8!vTemMP*#Qpo|fG%gm@YdCqt65K1pMbqw$N*f(09?obT*v@i z$N*f(09?obT*v@iz+UiYoFI4a-m~ZE(X(ff0a5}M&1JSIY5V`&rfZzEAJCUsV23?G zky(2{F4zNd(H@Wo?E$%B56D$}K%Tb;HpgM@OGA*ZgandHiLS16T9yn=X#z#t;6< zJa*4!+h_f$L+0>H%TC*OUpwc?Y73zMiLX5Ev_W3`-22?~z+889)|IyGyE~8rgPI49 z&x|Bm;(6eDqXezKG-ivlCcTL^jLdPizU3}+^7?;TZEt<&56v(3?lNzm{;c`+4G)=_ z3qLdG{`|Uqvuo1j(!Bi4jpml89x|6d{w4e7Q?E>!|Ge!x=H90k&1>hb zHDA2*E_3C=qxQ|>FMq!d(_eOSU{1Yh!MysJ-zUagbz{U{F0pR?t`u)Nup*AL6+vvF8nZ_95UmO+vmyf)M8 oHaPv)*!u0m^2#TSx!Ja{Lz|~KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000&ONklNrrq?F4w4EzkdCG?>pc3y(aJ-p+mPVvk1VRJc|6wxLwtc4#hDN-w`03Aq7Vj zps0W*0bt>nUDaFv2FAbxQN}4aEGSBzog|P;kpOT3z{D}Ts)IvmtmL;Gh>@Iv6M~}T z0f2?*Uwh>Mp8FeTBuTZk9-E>lGZjUdrYI;=6r~tYG8F~c0B8{4ML`Jqy1PRFnzFjN z%cH74e?gR$%)UMfX$thUH}(T4AG52vZK%8>JrpP2Q|l>FWcdL}lJAgYX}lzg`CUFA zqje9*acF66g)GaUL>Uu5JqA%$B18Zkx%BJ+9s}@;zi~zs)zsA7FGC>bh#())CW9p4pdzKRVr6{aJhP^9?%fNHedodOcxwJ$6vcn$ zd49SmNlY?*a2$u0mKMlLFBeqqJ`HP!Kc-y{MIwugecjgktH4!^I11oB0B^Zj_M7hv z7`3$?T9V{n@;v_tFYtM(^u_Z$nwpy-%Q669^05XKoNJBS)=87$3jCVlm^vOEOKeqqf$QAxY9}Tqv|g6h$W0{scilQ&SV9t3VVrcVW_3=b)&(WHCd< zeOcL-fyU?70h5?WhZaryFPw6(UOy}cbipATFp)XxzBFqh83O3JC(mxCgaL8`y1f9eEu zES+y;SOEYp0QilYWu+kxMvbRtMKBorA5j#o$yi3`&YnYkeLWf*8zG8f3_x5c)c>0S ziB~d4f>5+yqnM#ILk)ac5t`R8OJu0K0DRxgvh_pO>D#z*;|D!GJu4K&xW1ER8TIw` zIC6~Z{hLD2YxWd!tK&m;*9qx3^?&lZTN zoIM*;rc41zCKR&!6@Z_cA+}Nm!{hNx;JDydydY#7<%DBLkKy3Kg9royhPfxmaS?y} ziDfuO5*fPp=29f=r2cC@DL0`L5*!W(Zl6CNQ>IKwgi|~KR=Zg?Flb;4U}IUKwyOJf51{{ei%rB}t-;#Ey3D+=a7e&nEmFQ50iz#bcIYOd@QCUe3i( zhMw~ixfxA}G#Chi!1r#w6?fiwCoC3=k#3FxnD1uU)&T<}5g_X8>rv;eLok@!K29(g z?2kM3(SK%)(pB65U?m9T)5hfgb8-tBA;dS09S+>PawW>j%F+r5nS^MX?hgb$)B{3M z6zuzQA9iftku(sZD8>LWi^?_x1OQk_<7+JlS@l{+M+biQ#v9nPcdwDICIi@B=k;c% z6%0?Urz98*?35&l*0X%JZ`+Q82M?wke~KnIooo1hO9Fha1xB9{v32WKY}mLFlB8=m z%>Ync=k+G!Iv8$TTkElK9CuI<#Z0Ys{vJQJZQF*9j*gV$PjVc8#RYZQO;IHBX5WI$ z*|$RO?gmxg0O><7AZt&w2n9hH^NkK1IDoFsPOM(N8W|ay*4&){ehc7n)4>n~@zW5` z7ihKd`Fz;AWh;C>U&_8qwD%1F<0W~2;8 zh!1@t%d%=aNs{p4jt>)d1vyZa#7R1Wukj39~6)?*ddUO3oo!3hy42CEQHIgK$UhnMe#O~d@(*i`iNuNxrTT=f0f7R*` z;`Ht!7gJtW5|EkH>RskmGLCdhlnTex|3mOyi15Dhn)` zr*1%W`r!NTcjFBd{9Erqu2<)rW8h31dv|v?YBz7zYxc`JuQ$^$7=pn6K}#VWIeY{y zEiFg~MT4=1DZpyFPHbm;j6fiOKfU{>xS5z9Jq3nQ-C1Y{Q08XYpeAPsqVSp)SA4batF!?j2m(Y&LJ`5><&5%# zfk-qS1pqdXSWgTyH5s6@vlF|t^=W=Q-9biig^T03>1sW6b#>v?sZ(j=2wo5{gUZ4S zmNGC(a@7hJBJpXROjz-Egx%El*|~G4o_GFKo!3jKf+5M$ONyc%pZ?4KzaWuh1EW?* zFc^d=NvNWSVJ%&lQh$kr&BN(FA{QfKVk3h-PiCnYn}NG6CXh#>GNISiDE@3;5MFZD$Fy0~C?JTQKyj}Fisplu65Y~V0u3ok|eWgEt{K~ z!Sm(~GG2JRl(eMWZ?YzB1Q<#vEnqY?H|y>9%#+%fkg3HP=@wBHWTpvVq=v>Bg@=svQGLB;^}tjB zAQeSfpw-IE=&Y==o$4e~t1e>*BIVf9X@rnYy40X4VMf<^y;-CzD|6IZba!`~sxRUt ze>n(RH$za;@jxslMETOCyu%l@j?+Azloh!`)$Z=>G<87n1~W@VUl0H~AmCNu8@w;J zr6i&@@mKJFqWTV;4B)JiUN9s{(o5_cMJuv0Qthf)IZ%B-#NAG%Y%w4-gU26*R$P>O zMTecDk_Mw$7VsY54iO6G(AoGwMj>*dB3Shhz#;wB#aFIefzzp)JTa116j?QSwWp^i z?aI4v&w>EZfDr!3x8QPANW!nEd&Lw0N`o=p;oBfyo#$`$NE01pwv-~@$JY1S8gq*JMtPb;#b8iz2Dx|lR)kOTo6W5F+}7Wj0G%1#Z= zQ1iTH0KX5lMhG7&Oxzt&LU>MT#&RMDrmQW!7vPH ziUJQH+`3n*p%bBiK>U%aSyG?KJ-8S($1OY@GFoqh@TDkHBVa_%^MNyz>{Xn4B)4q_q zkWbJkaOA_`aP+Qps|8(SdkY{x`uOAiU9~d`-(PQGxyps<$ni2C42=mVOv;%s45~)E z4}^9Az}ma+g8wQQIoa7za`Vv9(Sa@7)Qe0>k~CT%nO4%_Oo1c_Le*r_smw8*jDXh1 z6#)7txS^o|*8}Mk*7#_WAbJ4g4Fxbrf{0kbvMfi4m%@U`!l`~R8XLb2V6@W&L8`jh z_AL8=a|RQpTcYD)GjEw0<}*;Bsou6tmoHxzVC3d#p7hjC5(J^Ttg^GS2X*k#MKhzy zN5yaj09?LKz!)}cnAYXR6u}_OLXl8JZzKwQ}rcIj`0Zt!hm|ZoME-G+3wS6q$G)a==b}boR;4Byt zB5Km4iE)+pH`j@XDk&}1x_r^ivYq6jMT@%_npO=$6}yTDUPLKM%-)AH|61soq3M2` zz4^Be-MCL~ZaeL)q`l9GWJQBmG+;@y zFldVQstT!um!ri!R2Fe-1mEv|?HfVS%Z45!l>;jG4?UDr5+BHz%8E0v8X8?b@L zJ2RxTEK=U~SyEkHU8e5Qr;Bd5;RdbC-RM0ytQU;Mi|;waFpO%jeeBq=gT@t3r!yj^ zLl8uNc~*OS`*k6rZn{zP(11_eEGzVb0RRlce5Ka9yu2J%t94Mom^CZ%s0oH)`eRtF zt*t{Ih{D1`J-yrixuJeAXo`AOOH@@gT#>e`~X9ynv>%$Zu3c>o(@ zz_{n0B_1tNHF@&nv=3Z};)?wI{21dQTzPkyn7xt?vRbW}K5d#-lMmf2+Z6)_09Y7{ zssostmy1!OMx~W2qJ4|`^VtZKHe7l4De$4r6*`gcH^YC>QS$g1f*_WuZMROJF&%;+ zV9J!6k(-+bf*^3E^9uIv-h+-SiJu@UNfHE6RNWhnKE{+J$p}s{GnL3}Vi*QN)boX#ty8B=!A&>c1gFy(lMoRuqJqKTklokL zvfD9l-aM@)J^(SkT?`nD7vJ+qb#?WbAQv2GUcOa&-G5LmF_PE49KsULuNqB1-TLen&+PMwNFhYp!uo1Q8ySg=6P75I;E z#oa#-@mg-Kt)1J|?fYEsC4F68@OtY|RaFIwHeNOy3Nhqv;=T9ZA2Md{*s)`=_Q40W_Vc>{l)G8BGiJfYYrSak;x95YG7o4ylpqK+ zH8qGBU7i=~BJK zihqg+gen+UmE}^cP6>j*`0?YD5)swa8!&zPG|Y3)Gkm{Rs*S~B!S`3M9&|vKELnow zT+Ks}PXl;O?V>6eixw@aw^}S8YFR|d0P)4=U%=&Zfo0i*?zigXJ&`1d`|iCL1qFk% z8CF?Yi5vADrVBhZ6ZNY(i$o(xuA|*lf1t z0|`W5rBk9*;B+F=NJ{R68eDjdlU3 zOqL@Oa{BbBre@P%52@bmFe#3J}wA? zX&G;}OdFiqH4TGFJbFLY{<>KmnlAFItE+z<9&!e`dP;>(09fT_*}s}< z#+yCL6)RT!I43K+f~M(|x8AHnpj0?b|HfJw2a=LZMlS+{Z8sTt&r00fb8co(J%5BB6~T z2}U1n-dtN42n0Xk1^#9u?X&E5IEFa}8-y3pyD2mvbq5131Ga73n&Kh zVGd;3?SlcregMA#@V=X62Q)Ej&;)Xw*Gsf@v_H%9{EtOZjIm!`Ma4-42$Q5%03QH& z)6KGn25U}+gm&DrbxT$-7<@$(#3hm}6WL6h|zh3>f2f%JO%U&94?>!{Jh$qqjlmI9PFao_Fka7a(+iIhM t{?Aah1L(N={{;Z&+$`I2J-p}t4*=&*>{!kRFfIT9002ovPDHLkV1fY;qj3NL diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.svg b/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.svg deleted file mode 100644 index bd7359ef..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff-icon.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.eps b/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.eps deleted file mode 100644 index ad5ec7ef6886ebee29c9ee0cbd7baa177690f3c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 551958 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

                  K2K`kLa-eS1o}?0>g$fll%hE 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�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

                  0!%8Iak-2^^5dGy)oVqMI@1!DvV{%`|9uut8)&a{ zE%u>nAVc1s?i>85`jMMni(tqd^e+iQd;^#DhJBsH2>DV#wK3ML+`=aMif78IHo@Fk zZCOz(^-7Us##Hp|uG+b4{~ePb-uo>PzjMR(b+Q(iZVxRw09#AN4tYfGg4O8^+;Nfchch7<7gm zS8r~=WeQ?h#N=;$SESS)XBV7Xh^IM0nY)P6bY{QhGHk?JZ;it9r8nywJFuafg_$^f zuF{#Q@&b|;O`ir=TN2ia>0D@P5J}JIx${GQdu_j)Y|r7)u`btSSM4;g6%s97j@@+a zs{W=1ok;3S({IceTa*`JwEK6~7x~MAKcCwxhI$>F>n8bKZeJyAS%GPwjIr+@yA`Ux zWYo)(J!q?fHM~Lk2HmL4gqk?C`L;t1>oI1s2cvE5y4TNMSuF1++KQS;=`MY%uu?jm z)#Zc@BnR=`D{qsI1RH4q6jBJ!*aTw-CGpSp8)<&hyVPu?U z^5`=9Ox5s`?Qo}-KAyT#Q^Q_+GbgnHE2vVw69Bv~D#=7cRG>Y6?s1D*e_ro(jK zdjotkaLjpb^o{3|0ov%98Eq{ZJ@iS`W#8CLhSMLTPtfDz9rBj`yj>Je)AM#VEtWru znb%v_)Vp(v`N`u&Y>}C9dvMS|@NZ;0`{gt7M!0P1;TzrVCT>qz4d?gB5nfM!cL8=g$y!!g6Uoi+#IP3EkCvvrRBC=p))3i5fV%?&gUNI0?g#>r3#ef1+LmAFS z3ILJl`5AJEKw+xgOM;&+8)lSg5%(g%Qb&!`c9?MH5UgCQrFHJhGQYb=j3Pl2lGFMk z;a|T{bUJY@@-&0q4C`QFKI_8B2t-=PlXkqkxP%m27Vi=mJZ>J3!$bA$8_Ns^dxcIm za}K-V*IqX0_@`$Xs&amRz9Z;bP;6IkB22oWi ze*Gcia{d0-?Xa~ZXr0RBeK6`P>($Y3>hFn><}C{(a#-ioT|MyII35O(AKpxfwmHww z7y%Q*dts`hZZdS~(i&S({yi+a{`P!i^!fWC-|zHobHcWm&bf)(Lx9Kycx)u>kAN7s06S)?Q+qgfY#&7Xc4wN}GKMfTt}$UMG}JY=l5 zn-=X0{lv?ALl9&)3YVx8dvAdV*@ZJt-%%|h9G;*2RN6fw3R06 zn?5j$ygxia(uF`!Shv3I+_Pq^W_tqtI7H&x) zN3u`wKKrLLmoE|K0jV8%^2cNSu}strM)~4EjyLu51~ts za$ic|d~AK$oHLI3?5)&_Ck+RD;M_j|&T;2)Z%pOrxZ0_?%rw8rO#6mrum{N(3trMq zv>AF4DB_q*XU;nn%~f{U;q`s(Ooiu7XY-pkc#m++juOCnY`aV7ms}Nx>15o}!4*v; zaRUJQllORj1E$19t1N@HY_vmwuLb}#03ldjdd#h0Niaw?m6zPD&aEhX5k|jQxMG>4 z5Vh57oP7qDcB?;@>hK-Y;6#+T51WNSdXs8Um%_ie)BE1(`{Ly(gRiokjDt>fW~O51 zc#D?GHf46_Cpw6`DQ}-@1LcTLcVNS`xesMASz5s4r?*DKHY~`fBo~ zulAvT8{bBVf#-Wq`M6bFmfY=Mf_uk!IENXx9J%@4In&9_C7Y*(%&%6l-B@VKng zE~ZrnTAX0ssPCF!@Y>WA-wJE5vsJOqDt2TcNShYizmb4%jWEoLo8^tn_2!79K; ztX_Kw0f1$AG^8Spf*^xsga4E8&3U)v_6k2?~iudmi+P1 zVA6Qz2_V#P*SVe>Q)T#$RSnh%W^w03)w1jR{Z{FY&U%(w?Z@?5Yo>UYv~poh$*$1I zuqM##&t%~68Ic8D@XLL)a0$do{ls72J0k+OY|(J7qdaa*nW>SVA(LWOUu!Vqlh!&9 z*1A^V#Wc65HE+NP<*jgYvUdNTsd{&n4trDESTxSUFsy}|Ef+tR-2Ap6#=NPQv_W-x zNaFb0aSUc<_LqGv7$&_AME^E-(2%czJO}$q3*b+hm%1c}Qxb}vZflpgBEMw4OsV#U z7$#SbyCg z)vh|q)`|m%*<3{3#gcq}u#D);y?s^1snm{K>j0T+MQ*}3`80b4Z<2mO|F1s?QR0{Z z5bKF)SG=F611jr~mdR|~XBlnL$u9=a?XWREoXgF6{1`6{>aEAP6}NlWXK8(IqS?jetfcnZmj+amMt?=*qGLe}1U zbX&&4hf^4n;YJI7x5oZCR~IiII>MXRT5&`DS8k;qDCyT{;hldTzwRWdgWVJ(+J_@j zt=F4|C_uZWU-2cNB){&KLR*Id;+2_w3{#%od2fv;EyR|_b#M@46Qj|(J{slHoJiMB z$Gq@sYouLg_I=PV9bYI@zdt(%Izvw|o>iCIuy>N4br*4>!a-^5?Z%7ygauM>)uLKd zoYi)l8f4)L_4Wyl*x9z`#Lck1Sq5#$A3lIVa$ez$H+b}@>na17P_ zh#uGY6s%75C_UFUP>g$RfJ%@7kR>Oy5De;C=C~_4LvLjLB~@HzHjUSI@0p^~W71sW z-I98W-6Cg=W{tRJmuWLvM7|2Po(VOn<(-T76w6M$$sWCK9LJlw=E>--TO_1>tNW?+ zzTrczuX(UexL`ZK_{S{VlNaX#j=2dk0JrCC-pJ)Cm3}UHYX0m*IZVz)y~UY@3{Ee~ zP3HaP=58a0>b>@;9%j@0ak%7H;_kI%D_W{(Fa`zJRilL;Z&fPoRrRHQt1&H@@FwOB zHs)HR@&>VVJr{`B=6Xz5YU<vsCMS(LI%ICOx@ z`Ln+GS|t#3S5BdBQ4Er6j;{8cX0&Tb8N+*V$kMzlKa~4nXN-Vz*>MUr4hx3E_9_ME zbFM$0*w6whc%IaisPRX>B7B6ostQ)pi<@wx!PY9!OQwmIHQwy1W)qt z*xF{;ZG5O^Zu1&Ek?2;b?F#T5CO2`-3c_M-8gYH&=s)sd^+~_j)>?{^H7I`y;VmiIBDsZ?XE+D({$Y z(m1=Sb%*k%ytI}cwf{_*hQjjIZ+FXfol*wc_dGIQ^22Z+UB-7lLEgsBSP13xJc;=kF}?~m(-|dT(qu`DZQqR-DNY8{OrWc(=GyjM&0gZclkB4 z&j@^Pe?tqVtB2%vJv%q69ou6E75ojNub)a&RN-YrPC!pgC#uksi@~iE)>9%q~VwDWurA_gmXRiz^{g z4_XMAqwmAna1ab4>}7U5LweNi{LVP4YkBReWn?F}@O%0FS8ERKIFf9(Tda*Ec#=bZ zWsQst_xi_Pc*xy(ces+CQ@Q@%4GlrE&_Ph;kJ|WrBb{*||dyPw)L7 z0O$?KPncD349%6pN~zyFwPs*SQah|F$q!6}pO^*zIjui!+rEs?C8}yE&-S)i$Gr9a zm@Ay`gNV(tY0~dhJ9=x@yb6IIA3KX>vqLJ*Y(58ix0Fo*i(qAubd7-=;CYag^QsmO zSqki=*QyM2{!?k!l7s$$syo?YC)gc7pX)&J$xd#BjBxcvNpS)7zd7mWa;>7yh(r6E zUOsJ|DiTHv;@|OQm6DA{ez;APQ6shD3kqgEyjH)UHufa9d(s6BJkZ7p5X{8fBQBr2 zk1&e751AV5FdLgYdu-uL*nrwO_iBy=A^`$75%`n-2f#_Fj;;QbAJ6XO!DVTXFZcD#+Hfmjtw z2YoUw8B#Rd)Ad{l^;@%&q?DI|N%YS$p7XSQ{k$y<9xr|`X5lXhDf=_|VLF)W;e?^{ z!^_wGtOtuzceiZ?C1pG8jO=N9R-~Jw!R^yN8GEjlg9vIh&_iOGg#COuSN^_%9#dEi zPQAbYIzh5@;qecaiMla{1HOAa_c~L4^gBf@A3h}*lf*`pMmqv%P`E?BZR9kGK$z6zy00grMU(yO4a+-1#_1&{Mh?tkea z61_<09c=IPT?b}ml3W`IWUn#N&KtgXCi|*Ba^4O$;YTj)+quz?m?w&crr399&(KC2 zJds+FeD8;zD-(C>VH}bs%=#*K`SzFVN~QAlQTa|B6pk$EjAp-frDv zJq=%6qKV31hQ-yYH=ix>`oKNKmoR#7^&`{kb&{8>QXl$=yaXIZHZe=3 z!SVYCk8rw|@XpDk$IX$5Z2aTd>${D?Ol!4^3VmZxOJDZ%O zI_Z0_P4s$^XfLZ;dg+W7C5}MB*kfS1VXJE(6)-5v2`$WAs9?)DB`%ng%BSkgCKrJsHZ=L95>uTG;`{h-*GGRh;x_yd;%jWQbyzxf2N+9LycmBxQ-G{vc zkO|?CV?nktzXvo4+upxG_v2O=d86)&^+E4Bjh4^$FJThKMe)|9dLF?JK?ZIiB~Af1=evN zo0j?MhgDTSCVYL3jK?zT+GT_A30aghqq}Xkom%R94s+=IU|UU*w>$!DY@Es=m+MEE zQc<}yGN>wDhY?*%dIP7MiD3r`Kd5^A$6#86RPuWux4pp&G2%jaAUVs~p1k1! zuy#qR;-3>Twu$`sGO#OqWKC>HY@W#BH7Zei`WHW>i#zLBZ6yRmW7PJ7AFcx5QW2?V z|60t^Rf7mYCfmXu+h;SF7^3aR(@A??R9B1ac_Dy6c6hW!sYZ%Fkl6j~dHXnj{P}}r z{G#5k$E*F^8!Z=xL+|73X$hb$FQLS|?ZQv&UFz+N2eYp?uyOuKZv9^8G&i=hlfY4- zxGkc1r&k)j@YU`n3EOl$ogS>L-jVuoHEsbfC?KSW0-*`|Xa9lFxlepRlB3fHr@Y7TvYQXH3^CQ1F0#9OD zi*0tb@HavAC|iEG^^jEizRfSCX>z|_}(?HphE7Rz@; zmQ;J7sy6n20Nj6SI5Hj~SNJYKBWZrB&nyy`96f+ctl_=EF8+qjgQX9fzPW~+fc7u} zg%-9(PI^0%_j39GLb0Q;VNs{>2D4FK)nk94%k`sCP2_j-=r^0mTUkI~^s+zb0bB!p z+8=8#4iJ}%LZQ%}p>`w`fzZROD`*$%qxAb#8TP)Pzhi|RR?%+rXzhNHkDkcckXZ}e zQ+GfY&Oq|KTEeISwyr%Is}l~|xjUt|gmghdH4gu-_^Usf`++;I&&SUEnb7{Bli#PS z(n|EE1h=E(qKY5+`fYQ3Q}?=w{XvozYCYgo?l2(+sP1XG(H4Z6L;VG;<#~@)^FPb( zwMJXZ5eR z#k3U7cQ*B-SX%x9yXedX`&@i%Dm^d_089$*~PH=ba19>3n1Y&Zs7TXd@Nt?{FC8Hta! z)bN={lKWg1`I54H3Zq$W56Z527&8n5SJ!gH0dK215+GcGxc11>M z`+gtwi}-bu7xPCc7V&!U$uoJSgU5G>V*MV2Q5;_Z6+1o0b?1<5*T}D*&N{t5Oh;=H zS^|@6Z}2S@UN<-B!StD|*zSDkF=0E_2G7Hi1OD7Dd^v;ZY7p7XFU6X}wE)8%*t72M1O2 z5HFsbRJju^KoF;$dZT}NjH;E=n2LGGvwN0CkL|lslG!k#I=cPWNTIi=9zMqxbGg*$ zI_TzM^WVjw9vii=S7n!W3+Gaud@LTTc5PR={yvL}r+&GXV344L;TmmVD5!9kQ7nO_ z`&`L+AmY=TAh73L4=0$Sk+tQt)L%bJEkN#!4j#LFEBYaS%kAcKsV@b#^#2K@njt zf2OHC%MH;Ix(2S*djv9B>YGg$RYune3ZU?`!3Fog*5g|ZU9duoblA#8t6^`Ww(6nA zmMija!81%Chy?4F$Q~Q7BOS~}WinWT%lyB;Qs;nF?RR>}*`tDhl=!rKrliyCRi1AD zR{Q(5)k#cH!c2nkvFg3RfCbdmj-(4Wx)Qd1>n4^|#oqwW!%YIl=4G@F>3>9u)TZXo zf!N9%;z4a0rGEr0BT;?kan;*t{g5TLRH>&*-7TOUu3Sp>vR0V5PV%>Q_IB+X>?~yY zdCjUO^n#vh$I7@@w3Mr9G)keWI;CAvYub~wCl(%oLHbAdE<|v(3X|vUOz#8%XF>Vo z{{#&d@bwAVQ5!!Pc;81BU2-kREWKR#JOvrd7I31&^6Z%-#THGTjQfiyY}E^~Ef~EO z)4XSCrMLooDTSUZ!=wgU1#B=D)pLPV>F2mMnX6wK4-)$8G_7434zg#8O3!~f(` z-Oo4`hO3|I<_20L*eKmVO}#sU@~vF!eBowg_fKQE$wJIHgv0!jw6I_(VF5Z`RwPg9 zBh&77UP?S{m|lkUoBf6*Z*(rfL}_}3Pw6s(7(NN)T0kltV<H|?# zuF9@B-6@qY-}olo+mEvI&&!@JfY*AyYRc;2RBGAm=IMcRu-zV+0!dHLUd}MUhIV}& zEfD*|?sdqQYFNOh)H1NYXt3OqxSsA?)$svkUZI*ivaGd6R$c~%;Lq>Z|Kr*AC8#qk zjA>NQK&c`exDQ7zZq2_%x`OH?UD@<}Uf>W(#kaIKBw7e_&= zf;}vmE1G-c^Ja`(9fDYv7IUSrSI{-+`CX?8WJDyV6gEyzDf+MJ6%yFuXkrJ8MkD?m zBQqU4mq&FCSvN{|_g#sDS4ZHbfaU%gmyrMKTzctw>c$zwu#BaJmj>(2=vT(BJ*!y; z#XSyNo=P2MHBX3#K-sfZqzOH1SZCrYS_01(;HpMrx-Eyp?_H%Ui|jp`M3#D5a-e4cON*uvITDmoHbkgT-gzX_gg3D`LU6w zLH4oc0p9>5^B4gZzPBNO$E=486N1L8Qg@ihh&J0Sq`k7ci@G@XqPsA;iVON?2|I__ zj7RnT^Me#^fAUJgk1v!L_5J*q!@~1m{@3}wec>6nx5<$BgOQ|)%xh%xwQsfRI1R^9N>Ge>PF4PoH-H2nAEN=yF2i?WZ-2Cy7W@U~=ZJBb@Fvgc&IgqE2ZtqIxsW+Y z-R{^qKDHsnOpL`_KO7Q~D02GHNHgS4de$-XwDY@aUO+gw6Gy0hyI%Km>KJw_H}ytB zXHj{c)V#tJ`^>WXH+X~>R;Nh?{MKl6t&%=bNeYd-rvY_|DF zK%^?!9?=_6)|3&-jn`Ox{fdLt?{Rk2FL7ewx-lrT$G^6{mGCW}WEt>mjbc11*7u9O zp!9UGK4w(;{ed&tZ&t+j6GygA$(v?Vv)>%h5?M8isWnaPS7euar#UxrPy6w*-kKC< zFag&mLmgPnz=JagSNz<*n^JISciw4`--)+Y%dGj${qwlf@yTA@zyv<+e=ohKrs|e| z_)f#XYJQu65Dp3nU;?I9c-BZN_j@t|Xc%u>8B>{|Rw4r+0BMp#=99-{mq+7ib7WRJ z-uFPtOb9s;k$23eiZNVYrp$f`Q@G;mTqJXN<2Ue=%lq((D%srI^oj%0AMn&UrT5Bw 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

                  xG<%5W~0dHg8~>Gr2UnpSHR##YNdA`{-}WJK&);-}wDonBh_TF!5V$)RgZ8&~E2obb0lSSWp`^oo1Xd*6ulOVQ(0$=F=>7 z+CcOu8H$S({LCvLLfW4?daJ;x~??>_0}OM;AO_EH#XOzMGHPCllG~z>V_tfGyy!2rASxrw=Ft z?i_grDtt^|xcIjMrNM8c#912Gs8E@uwY`@kHH;-I&!Sy%4#^aIK7g)cYthElpkrG5^HOtra65|E0Et2Raj0h&^k$Br0vWC8CN&fitY+W5Bu&*|$hm$;wWsI-9nCSD=rmi)WMZ&YG!T%$rw z7O)o1Lsj^uOB~EYkC3+a4|>C*a0Nco8!_jWDpW|R#n1iJ`2Jc;wD91Z;!T@Sw2T`n z+FHK%S0R79Zk#MJy}s%Tc2j&o9px7}CbX309<=PVYRa5=Dr(C7;jd0jnOA20nsOZ~ wx2`Gk$8FtOZCYs675$tbwy7yMEC)=f4RsA2D%;j-Z?Rqrc^ycH{1*=J9|{#^mjD0& diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.png b/spec/fixture/node_modules/gulp/node_modules/liftoff/artwork/liftoff.png deleted file mode 100644 index 0403fa6a0483f3967ccd9c277b69850b90ba80dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10492 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 - - - - - - - - - - - - - - - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/index.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/index.js deleted file mode 100644 index 5c8d4b12..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/index.js +++ /dev/null @@ -1,168 +0,0 @@ -const fs = require('fs'); -const util = require('util'); -const path = require('path'); -const EE = require('events').EventEmitter; - -const extend = require('extend'); -const resolve = require('resolve'); -const flaggedRespawn = require('flagged-respawn'); - -const findCwd = require('./lib/find_cwd'); -const findConfig = require('./lib/find_config'); -const fileSearch = require('./lib/file_search'); -const parseOptions = require('./lib/parse_options'); -const silentRequire = require('./lib/silent_require'); -const buildConfigName = require('./lib/build_config_name'); - -function Liftoff (opts) { - EE.call(this); - extend(this, parseOptions(opts)); -} -util.inherits(Liftoff, EE); - -Liftoff.prototype.requireLocal = function (module, basedir) { - try { - var result = require(resolve.sync(module, {basedir: basedir})); - this.emit('require', module, result); - return result; - } catch (e) { - this.emit('requireFail', module, e); - } -}; - -Liftoff.prototype.buildEnvironment = function (opts) { - opts = opts||{}; - - // get modules we want to preload - var preload = opts.require||[]; - - // ensure items to preload is an array - if (!Array.isArray(preload)) { - preload = [preload]; - } - - // make a copy of search paths that can be mutated for this run - var searchPaths = this.searchPaths.slice(); - - // calculate current cwd - var cwd = findCwd(opts); - - // if cwd was provided explicitly, only use it for searching config - if (opts.cwd) { - searchPaths = [cwd]; - } else { - // otherwise just search in cwd first - searchPaths.unshift(cwd); - } - - // calculate the regex to use for finding the config file - var configNameSearch = buildConfigName({ - configName: this.configName, - extensions: Object.keys(this.extensions) - }); - - // calculate configPath - var configPath = findConfig({ - configNameSearch: configNameSearch, - searchPaths: searchPaths, - configPath: opts.configPath - }); - - // if we have a config path, save the directory it resides in. - var configBase; - if (configPath) { - configBase = path.dirname(configPath); - // if cwd wasn't provided explicitly, it should match configBase - if (!opts.cwd) { - cwd = configBase; - } - // resolve symlink if needed - if(fs.lstatSync(configPath).isSymbolicLink()) { - configPath = fs.realpathSync(configPath); - } - } - - // TODO: break this out into lib/ - // locate local module and package next to config or explicitly provided cwd - var modulePath, modulePackage; - try { - modulePath = resolve.sync(this.moduleName, {basedir: configBase || cwd}); - modulePackage = silentRequire(fileSearch('package.json', [modulePath])); - } catch (e) {} - - // if we have a configuration but we failed to find a local module, maybe - // we are developing against ourselves? - if (!modulePath && configPath) { - // check the package.json sibling to our config to see if its `name` - // matches the module we're looking for - modulePackage = silentRequire(fileSearch('package.json', [configBase])); - if (modulePackage && modulePackage.name === this.moduleName) { - // if it does, our module path is `main` inside package.json - modulePath = path.join(configBase, modulePackage.main||'index.js'); - cwd = configBase; - } else { - // clear if we just required a package for some other project - modulePackage = {}; - } - } - - // get extension of config name, taking anything after the -first- dot - var configExtension = /(\.[^\/]*)?$/.exec(configPath)[0]; - - // preload module needed for config if any has been specified. - var requireForExtension = this.extensions[configExtension]; - if (requireForExtension) { - preload.push(requireForExtension); - } - - // preload modules, if any - if (preload.length) { - // unique results first - preload.filter(function (value, index, self) { - return self.indexOf(value) === index; - }).forEach(function (dep) { - this.requireLocal(dep, findCwd(opts)); - }, this); - } - - return { - cwd: cwd, - require: preload, - configNameSearch: configNameSearch, - configPath: configPath, - configBase: configBase, - modulePath: modulePath, - modulePackage: modulePackage||{} - }; -}; - -Liftoff.prototype.launch = function (opts, fn) { - if (typeof fn !== 'function') { - throw new Error('You must provide a callback function.'); - } - - process.title = this.processTitle; - - var completion = opts.completion; - if (completion && this.completions) { - return this.completions(completion); - } - - if (this.nodeFlags) { - flaggedRespawn(this.nodeFlags, process.argv, function (ready, child) { - if (child !== process) { - this.emit('respawn', process.argv.filter(function (flag) { - return this.nodeFlags.indexOf(flag) !== -1; - }.bind(this)), child); - } - if (ready) { - fn.call(this, this.buildEnvironment(opts)); - } - }.bind(this)); - } else { - fn.call(this, this.buildEnvironment(opts)); - } - -}; - -module.exports = Liftoff; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/build_config_name.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/build_config_name.js deleted file mode 100644 index 31f1882e..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/build_config_name.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = function (opts) { - opts = opts || {}; - var configName = opts.configName; - var extensions = opts.extensions; - if (!configName) { - throw new Error('Please specify a configName.'); - } - if (configName instanceof RegExp) { - return [configName]; - } - if (!Array.isArray(extensions)) { - throw new Error('Please provide an array of valid extensions.'); - } - return extensions.map(function (ext) { - return configName+ext; - }); -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/file_search.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/file_search.js deleted file mode 100644 index c985d38a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/file_search.js +++ /dev/null @@ -1,14 +0,0 @@ -const findup = require('findup-sync'); - -module.exports = function (search, paths) { - var path; - var len = paths.length; - for (var i=0; i < len; i++) { - if (path) { - break; - } else { - path = findup(search, {cwd: paths[i], nocase: true}); - } - } - return path; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_config.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_config.js deleted file mode 100644 index 71c3f077..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_config.js +++ /dev/null @@ -1,25 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const fileSearch = require('./file_search'); - -module.exports = function (opts) { - opts = opts || {}; - var configNameSearch = opts.configNameSearch; - var configPath = opts.configPath; - var searchPaths = opts.searchPaths; - // only search for a config if a path to one wasn't explicitly provided - if (!configPath) { - if (!Array.isArray(searchPaths)) { - throw new Error('Please provide an array of paths to search for config in.'); - } - if (!configNameSearch) { - throw new Error('Please provide a configNameSearch.'); - } - configPath = fileSearch(configNameSearch, searchPaths); - } - // confirm the configPath exists and return an absolute path to it - if (fs.existsSync(configPath)) { - return path.resolve(configPath); - } - return null; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_cwd.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_cwd.js deleted file mode 100644 index 55330e51..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/find_cwd.js +++ /dev/null @@ -1,16 +0,0 @@ -const path = require('path'); - -module.exports = function (opts) { - opts = opts||{}; - var cwd = opts.cwd; - var configPath = opts.configPath; - // if a path to the desired config was specified - // but no cwd was provided, use configPath dir - if (typeof configPath === 'string' && !cwd) { - cwd = path.dirname(path.resolve(configPath)); - } - if (typeof cwd === 'string') { - return path.resolve(cwd); - } - return process.cwd(); -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/parse_options.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/parse_options.js deleted file mode 100644 index de1dabfd..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/parse_options.js +++ /dev/null @@ -1,33 +0,0 @@ -const extend = require('extend'); - -module.exports = function (opts) { - var defaults = { - extensions: { - '.js': null, - '.json': null - }, - searchPaths: [] - }; - opts = opts||{}; - if (opts.name) { - if (!opts.processTitle) { - opts.processTitle = opts.name; - } - if (!opts.configName) { - opts.configName = opts.name+'file'; - } - if (!opts.moduleName) { - opts.moduleName = opts.name; - } - } - if (!opts.processTitle) { - throw new Error('You must specify a processTitle.'); - } - if (!opts.configName) { - throw new Error('You must specify a configName.'); - } - if (!opts.moduleName) { - throw new Error('You must specify a moduleName.'); - } - return extend(defaults, opts); -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/silent_require.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/silent_require.js deleted file mode 100644 index 7b4dfe4e..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/lib/silent_require.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = function (path) { - try { - return require(path); - } catch (e) {} -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.npmignore b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.npmignore deleted file mode 100644 index 30d74d25..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.travis.yml b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.travis.yml deleted file mode 100644 index 912080aa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: node_js -node_js: - - "0.11" - - "0.10" - - "0.9" - - "0.8" - - "0.6" - - "0.4" -before_install: - - '[ "${TRAVIS_NODE_VERSION}" == "0.6" ] || npm install -g npm@~1.4.6' -matrix: - fast_finish: true - allow_failures: - - node_js: "0.11" - - node_js: "0.9" - - node_js: "0.6" - - node_js: "0.4" - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/LICENSE deleted file mode 100644 index e16d6a56..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Stefan Thomas - -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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/README.md deleted file mode 100644 index 715f666e..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/README.md +++ /dev/null @@ -1,60 +0,0 @@ -[![Build Status][1]][2] [![dependency status][9]][10] [![dev dependency status][11]][12] - -# extend() for Node.js [![Version Badge][8]][3] - -`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true. - -## Installation - -This package is available on [npm][3] as: `extend` - -``` sh -npm install extend -``` - -## Usage - -**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)** - -*Extend one object with one or more others, returning the modified object.* - -Keep in mind that the target object will be modified, and will be returned from extend(). - -If a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s). -Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. -Warning: passing `false` as the first argument is not supported. - -### Arguments - -* `deep` *Boolean* (optional) -If set, the merge becomes recursive (i.e. deep copy). -* `target` *Object* -The object to extend. -* `object1` *Object* -The object that will be merged into the first. -* `objectN` *Object* (Optional) -More objects to merge into the first. - -## License - -`node-extend` is licensed under the [MIT License][4]. - -## Acknowledgements - -All credit to the jQuery authors for perfecting this amazing utility. - -Ported to Node.js by [Stefan Thomas][5] with contributions by [Jonathan Buchanan][6] and [Jordan Harband][7]. - -[1]: https://travis-ci.org/justmoon/node-extend.svg -[2]: https://travis-ci.org/justmoon/node-extend -[3]: https://npmjs.org/package/extend -[4]: http://opensource.org/licenses/MIT -[5]: https://github.com/justmoon -[6]: https://github.com/insin -[7]: https://github.com/ljharb -[8]: http://vb.teelaun.ch/justmoon/node-extend.svg -[9]: https://david-dm.org/justmoon/node-extend.svg -[10]: https://david-dm.org/justmoon/node-extend -[11]: https://david-dm.org/justmoon/node-extend/dev-status.svg -[12]: https://david-dm.org/justmoon/node-extend#info=devDependencies - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/component.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/component.json deleted file mode 100644 index 378c7f55..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/component.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "extend", - "author": "Stefan Thomas (http://www.justmoon.net)", - "version": "1.3.0", - "description": "Port of jQuery.extend for node.js and the browser.", - "scripts": [ - "index.js" - ], - "contributors": [ - { - "name": "Jordan Harband", - "url": "https://github.com/ljharb" - } - ], - "keywords": [ - "extend", - "clone", - "merge" - ], - "repository" : { - "type": "git", - "url": "https://github.com/justmoon/node-extend.git" - }, - "dependencies": { - }, - "devDependencies": { - "tape" : "~2.12.3", - "covert": "~0.4.0" - } -} - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/index.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/index.js deleted file mode 100644 index 06f3c120..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/index.js +++ /dev/null @@ -1,80 +0,0 @@ -var hasOwn = Object.prototype.hasOwnProperty; -var toString = Object.prototype.toString; -var undefined; - -var isPlainObject = function isPlainObject(obj) { - "use strict"; - if (!obj || toString.call(obj) !== '[object Object]' || obj.nodeType || obj.setInterval) { - return false; - } - - var has_own_constructor = hasOwn.call(obj, 'constructor'); - var has_is_property_of_method = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !has_own_constructor && !has_is_property_of_method) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) {} - - return key === undefined || hasOwn.call(obj, key); -}; - -module.exports = function extend() { - "use strict"; - var options, name, src, copy, copyIsArray, clone, - target = arguments[0], - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if (typeof target === "boolean") { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } else if (typeof target !== "object" && typeof target !== "function" || target == undefined) { - target = {}; - } - - for (; i < length; ++i) { - // Only deal with non-null/undefined values - if ((options = arguments[i]) != null) { - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target === copy) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && Array.isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[name] = extend(deep, clone, copy); - - // Don't bring in undefined values - } else if (copy !== undefined) { - target[name] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/package.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/package.json deleted file mode 100644 index af0f4c93..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/extend/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "extend", - "author": { - "name": "Stefan Thomas", - "email": "justmoon@members.fsf.org", - "url": "http://www.justmoon.net" - }, - "version": "1.3.0", - "description": "Port of jQuery.extend for node.js and the browser", - "main": "index", - "scripts": { - "test": "node test/index.js", - "coverage": "covert test/index.js", - "coverage-quiet": "covert test/index.js --quiet" - }, - "contributors": [ - { - "name": "Jordan Harband", - "url": "https://github.com/ljharb" - } - ], - "keywords": [ - "extend", - "clone", - "merge" - ], - "repository": { - "type": "git", - "url": "https://github.com/justmoon/node-extend.git" - }, - "dependencies": {}, - "devDependencies": { - "tape": "~2.13.2", - "covert": "~0.4.0" - }, - "gitHead": "30bf952975a8551c8aabc3aed5e812455847e37a", - "bugs": { - "url": "https://github.com/justmoon/node-extend/issues" - }, - "homepage": "https://github.com/justmoon/node-extend", - "_id": "extend@1.3.0", - "_shasum": "d1516fb0ff5624d2ebf9123ea1dac5a1994004f8", - "_from": "extend@~1.3.0", - "_npmVersion": "1.4.14", - "_npmUser": { - "name": "ljharb", - "email": "ljharb@gmail.com" - }, - "maintainers": [ - { - "name": "justmoon", - "email": "justmoon@members.fsf.org" - }, - { - "name": "ljharb", - "email": "ljharb@gmail.com" - } - ], - "dist": { - "shasum": "d1516fb0ff5624d2ebf9123ea1dac5a1994004f8", - "tarball": "http://registry.npmjs.org/extend/-/extend-1.3.0.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/extend/-/extend-1.3.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.jshintrc b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.jshintrc deleted file mode 100644 index 87189522..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.jshintrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "loopfunc": true, - "curly": true, - "eqeqeq": true, - "immed": true, - "latedef": true, - "newcap": true, - "noarg": true, - "sub": true, - "undef": true, - "unused": true, - "boss": true, - "eqnull": true, - "node": true -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.npmignore b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.npmignore deleted file mode 100644 index e69de29b..00000000 diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.travis.yml b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.travis.yml deleted file mode 100644 index b30fcb75..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -node_js: - - 0.8 -before_script: - - npm install -g grunt-cli diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/Gruntfile.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/Gruntfile.js deleted file mode 100644 index 2f964a5b..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/Gruntfile.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -module.exports = function(grunt) { - - // Project configuration. - grunt.initConfig({ - nodeunit: { - files: ['test/**/*_test.js'], - }, - jshint: { - options: { - jshintrc: '.jshintrc' - }, - all: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'] - } - }); - - // Load plugins. - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-nodeunit'); - - // Default task. - grunt.registerTask('default', ['jshint', 'nodeunit']); - -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/LICENSE-MIT b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/LICENSE-MIT deleted file mode 100644 index bb2aad6d..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 "Cowboy" Ben Alman - -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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/README.md deleted file mode 100644 index 5459b93f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# findup-sync [![Build Status](https://secure.travis-ci.org/cowboy/node-findup-sync.png?branch=master)](http://travis-ci.org/cowboy/node-findup-sync) - -Find the first file matching a given pattern in the current directory or the nearest ancestor directory. - -## Getting Started -Install the module with: `npm install findup-sync` - -```js -var findup = require('findup-sync'); - -// Start looking in the CWD. -var filepath1 = findup('{a,b}*.txt'); - -// Start looking somewhere else, and ignore case (probably a good idea). -var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true}); -``` - -## Usage - -```js -findup(patternOrPatterns [, minimatchOptions]) -``` - -### patternOrPatterns -Type: `String` or `Array` -Default: none - -One or more wildcard glob patterns. Or just filenames. - -### minimatchOptions -Type: `Object` -Default: `{}` - -Options to be passed to [minimatch](https://github.com/isaacs/minimatch). - -Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here. - -## Contributing -In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). - -## Release History -2014-03-14 - v0.1.3 - Updated dependencies. -2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform. -2012-11-15 - v0.1.1 - Now works without an options object. -2012-11-01 - v0.1.0 - Initial release. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/lib/findup-sync.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/lib/findup-sync.js deleted file mode 100644 index 742a4781..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/lib/findup-sync.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * findup-sync - * https://github.com/cowboy/node-findup-sync - * - * Copyright (c) 2013 "Cowboy" Ben Alman - * Licensed under the MIT license. - */ - -'use strict'; - -// Nodejs libs. -var path = require('path'); - -// External libs. -var glob = require('glob'); -var _ = require('lodash'); - -// Search for a filename in the given directory or all parent directories. -module.exports = function(patterns, options) { - // Normalize patterns to an array. - if (!Array.isArray(patterns)) { patterns = [patterns]; } - // Create globOptions so that it can be modified without mutating the - // original object. - var globOptions = Object.create(options || {}); - globOptions.maxDepth = 1; - globOptions.cwd = path.resolve(globOptions.cwd || '.'); - - var files, lastpath; - do { - // Search for files matching patterns. - files = _(patterns).map(function(pattern) { - return glob.sync(pattern, globOptions); - }).flatten().uniq().value(); - // Return file if found. - if (files.length > 0) { - return path.resolve(path.join(globOptions.cwd, files[0])); - } - // Go up a directory. - lastpath = globOptions.cwd; - globOptions.cwd = path.resolve(globOptions.cwd, '..'); - // If parentpath is the same as basedir, we can't go any higher. - } while (globOptions.cwd !== lastpath); - - // No files were found! - return null; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.npmignore b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.npmignore deleted file mode 100644 index 2af4b71c..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -.*.swp -test/a/ diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.travis.yml b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.travis.yml deleted file mode 100644 index baa0031d..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - 0.8 diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/LICENSE deleted file mode 100644 index 0c44ae71..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) Isaac Z. Schlueter ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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 AUTHOR 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 AUTHOR 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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/README.md deleted file mode 100644 index cc691645..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# Glob - -Match files using the patterns the shell uses, like stars and stuff. - -This is a glob implementation in JavaScript. It uses the `minimatch` -library to do its matching. - -## Attention: node-glob users! - -The API has changed dramatically between 2.x and 3.x. This library is -now 100% JavaScript, and the integer flags have been replaced with an -options object. - -Also, there's an event emitter class, proper tests, and all the other -things you've come to expect from node modules. - -And best of all, no compilation! - -## Usage - -```javascript -var glob = require("glob") - -// options is optional -glob("**/*.js", options, function (er, files) { - // files is an array of filenames. - // If the `nonull` option is set, and nothing - // was found, then files is ["**/*.js"] - // er is an error object or null. -}) -``` - -## Features - -Please see the [minimatch -documentation](https://github.com/isaacs/minimatch) for more details. - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` -* [minimatch documentation](https://github.com/isaacs/minimatch) - -## glob(pattern, [options], cb) - -* `pattern` {String} Pattern to be matched -* `options` {Object} -* `cb` {Function} - * `err` {Error | null} - * `matches` {Array} filenames found matching the pattern - -Perform an asynchronous glob search. - -## glob.sync(pattern, [options]) - -* `pattern` {String} Pattern to be matched -* `options` {Object} -* return: {Array} filenames found matching the pattern - -Perform a synchronous glob search. - -## Class: glob.Glob - -Create a Glob object by instanting the `glob.Glob` class. - -```javascript -var Glob = require("glob").Glob -var mg = new Glob(pattern, options, cb) -``` - -It's an EventEmitter, and starts walking the filesystem to find matches -immediately. - -### new glob.Glob(pattern, [options], [cb]) - -* `pattern` {String} pattern to search for -* `options` {Object} -* `cb` {Function} Called when an error occurs, or matches are found - * `err` {Error | null} - * `matches` {Array} filenames found matching the pattern - -Note that if the `sync` flag is set in the options, then matches will -be immediately available on the `g.found` member. - -### Properties - -* `minimatch` The minimatch object that the glob uses. -* `options` The options object passed in. -* `error` The error encountered. When an error is encountered, the - glob object is in an undefined state, and should be discarded. -* `aborted` Boolean which is set to true when calling `abort()`. There - is no way at this time to continue a glob search after aborting, but - you can re-use the statCache to avoid having to duplicate syscalls. -* `statCache` Collection of all the stat results the glob search - performed. -* `cache` Convenience object. Each field has the following possible - values: - * `false` - Path does not exist - * `true` - Path exists - * `1` - Path exists, and is not a directory - * `2` - Path exists, and is a directory - * `[file, entries, ...]` - Path exists, is a directory, and the - array value is the results of `fs.readdir` - -### Events - -* `end` When the matching is finished, this is emitted with all the - matches found. If the `nonull` option is set, and no match was found, - then the `matches` list contains the original pattern. The matches - are sorted, unless the `nosort` flag is set. -* `match` Every time a match is found, this is emitted with the matched. -* `error` Emitted when an unexpected error is encountered, or whenever - any fs error occurs if `options.strict` is set. -* `abort` When `abort()` is called, this event is raised. - -### Methods - -* `abort` Stop the search. - -### Options - -All the options that can be passed to Minimatch can also be passed to -Glob to change pattern matching behavior. Also, some have been added, -or have glob-specific ramifications. - -All options are false by default, unless otherwise noted. - -All options are added to the glob object, as well. - -* `cwd` The current working directory in which to search. Defaults - to `process.cwd()`. -* `root` The place where patterns starting with `/` will be mounted - onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix - systems, and `C:\` or some such on Windows.) -* `dot` Include `.dot` files in normal matches and `globstar` matches. - Note that an explicit dot in a portion of the pattern will always - match dot files. -* `nomount` By default, a pattern starting with a forward-slash will be - "mounted" onto the root setting, so that a valid filesystem path is - returned. Set this flag to disable that behavior. -* `mark` Add a `/` character to directory matches. Note that this - requires additional stat calls. -* `nosort` Don't sort the results. -* `stat` Set to true to stat *all* results. This reduces performance - somewhat, and is completely unnecessary, unless `readdir` is presumed - to be an untrustworthy indicator of file existence. It will cause - ELOOP to be triggered one level sooner in the case of cyclical - symbolic links. -* `silent` When an unusual error is encountered - when attempting to read a directory, a warning will be printed to - stderr. Set the `silent` option to true to suppress these warnings. -* `strict` When an unusual error is encountered - when attempting to read a directory, the process will just continue on - in search of other matches. Set the `strict` option to raise an error - in these cases. -* `cache` See `cache` property above. Pass in a previously generated - cache object to save some fs calls. -* `statCache` A cache of results of filesystem information, to prevent - unnecessary stat calls. While it should not normally be necessary to - set this, you may pass the statCache from one glob() call to the - options object of another, if you know that the filesystem will not - change between calls. (See "Race Conditions" below.) -* `sync` Perform a synchronous glob search. -* `nounique` In some cases, brace-expanded patterns can result in the - same file showing up multiple times in the result set. By default, - this implementation prevents duplicates in the result set. - Set this flag to disable that behavior. -* `nonull` Set to never return an empty set, instead returning a set - containing the pattern itself. This is the default in glob(3). -* `nocase` Perform a case-insensitive match. Note that case-insensitive - filesystems will sometimes result in glob returning results that are - case-insensitively matched anyway, since readdir and stat will not - raise an error. -* `debug` Set to enable debug logging in minimatch and glob. -* `globDebug` Set to enable debug logging in glob, but not minimatch. - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between node-glob and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then glob returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. - -## Windows - -**Please only use forward-slashes in glob expressions.** - -Though windows uses either `/` or `\` as its path separator, only `/` -characters are used by this glob implementation. You must use -forward-slashes **only** in glob expressions. Back-slashes will always -be interpreted as escape characters, not path separators. - -Results from absolute patterns such as `/foo/*` are mounted onto the -root setting using `path.join`. On windows, this will by default result -in `/foo/*` matching `C:\foo\bar.txt`. - -## Race Conditions - -Glob searching, by its very nature, is susceptible to race conditions, -since it relies on directory walking and such. - -As a result, it is possible that a file that exists when glob looks for -it may have been deleted or modified by the time it returns the result. - -As part of its internal implementation, this program caches all stat -and readdir calls that it makes, in order to cut down on system -overhead. However, this also makes it even more susceptible to races, -especially if the cache or statCache objects are reused between glob -calls. - -Users are thus advised not to use a glob result as a guarantee of -filesystem state in the face of rapid changes. For the vast majority -of operations, this is never a problem. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/g.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/g.js deleted file mode 100644 index be122df0..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/g.js +++ /dev/null @@ -1,9 +0,0 @@ -var Glob = require("../").Glob - -var pattern = "test/a/**/[cg]/../[cg]" -console.log(pattern) - -var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { - console.log("matches", matches) -}) -console.log("after") diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/usr-local.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/usr-local.js deleted file mode 100644 index 327a425e..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/examples/usr-local.js +++ /dev/null @@ -1,9 +0,0 @@ -var Glob = require("../").Glob - -var pattern = "{./*/*,/*,/usr/local/*}" -console.log(pattern) - -var mg = new Glob(pattern, {mark: true}, function (er, matches) { - console.log("matches", matches) -}) -console.log("after") diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js deleted file mode 100644 index f646c448..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/glob.js +++ /dev/null @@ -1,728 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// readdir(PREFIX) as ENTRIES -// If fails, END -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $]) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $]) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - - - -module.exports = glob - -var fs = require("fs") -, minimatch = require("minimatch") -, Minimatch = minimatch.Minimatch -, inherits = require("inherits") -, EE = require("events").EventEmitter -, path = require("path") -, isDir = {} -, assert = require("assert").ok - -function glob (pattern, options, cb) { - if (typeof options === "function") cb = options, options = {} - if (!options) options = {} - - if (typeof options === "number") { - deprecated() - return - } - - var g = new Glob(pattern, options, cb) - return g.sync ? g.found : g -} - -glob.fnmatch = deprecated - -function deprecated () { - throw new Error("glob's interface has changed. Please see the docs.") -} - -glob.sync = globSync -function globSync (pattern, options) { - if (typeof options === "number") { - deprecated() - return - } - - options = options || {} - options.sync = true - return glob(pattern, options) -} - -this._processingEmitQueue = false - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (!(this instanceof Glob)) { - return new Glob(pattern, options, cb) - } - - if (typeof options === "function") { - cb = options - options = null - } - - if (typeof cb === "function") { - this.on("error", cb) - this.on("end", function (matches) { - cb(null, matches) - }) - } - - options = options || {} - - this._endEmitted = false - this.EOF = {} - this._emitQueue = [] - - this.paused = false - this._processingEmitQueue = false - - this.maxDepth = options.maxDepth || 1000 - this.maxLength = options.maxLength || Infinity - this.cache = options.cache || {} - this.statCache = options.statCache || {} - - this.changedCwd = false - var cwd = process.cwd() - if (!options.hasOwnProperty("cwd")) this.cwd = cwd - else { - this.cwd = options.cwd - this.changedCwd = path.resolve(options.cwd) !== cwd - } - - this.root = options.root || path.resolve(this.cwd, "/") - this.root = path.resolve(this.root) - if (process.platform === "win32") - this.root = this.root.replace(/\\/g, "/") - - this.nomount = !!options.nomount - - if (!pattern) { - throw new Error("must provide pattern") - } - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - this.strict = options.strict !== false - this.dot = !!options.dot - this.mark = !!options.mark - this.sync = !!options.sync - this.nounique = !!options.nounique - this.nonull = !!options.nonull - this.nosort = !!options.nosort - this.nocase = !!options.nocase - this.stat = !!options.stat - - this.debug = !!options.debug || !!options.globDebug - if (this.debug) - this.log = console.error - - this.silent = !!options.silent - - var mm = this.minimatch = new Minimatch(pattern, options) - this.options = mm.options - pattern = this.pattern = mm.pattern - - this.error = null - this.aborted = false - - // list of all the patterns that ** has resolved do, so - // we can avoid visiting multiple times. - this._globstars = {} - - EE.call(this) - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - this.minimatch.set.forEach(iterator.bind(this)) - function iterator (pattern, i, set) { - this._process(pattern, 0, i, function (er) { - if (er) this.emit("error", er) - if (-- n <= 0) this._finish() - }) - } -} - -Glob.prototype.log = function () {} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - - var nou = this.nounique - , all = nou ? [] : {} - - for (var i = 0, l = this.matches.length; i < l; i ++) { - var matches = this.matches[i] - this.log("matches[%d] =", i, matches) - // do like the shell, and spit out the literal glob - if (!matches) { - if (this.nonull) { - var literal = this.minimatch.globSet[i] - if (nou) all.push(literal) - else all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) all.push.apply(all, m) - else m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) all = Object.keys(all) - - if (!this.nosort) { - all = all.sort(this.nocase ? alphasorti : alphasort) - } - - if (this.mark) { - // at *some* point we statted all of these - all = all.map(this._mark, this) - } - - this.log("emitting end", all) - - this.EOF = this.found = all - this.emitMatch(this.EOF) -} - -function alphasorti (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return alphasort(a, b) -} - -function alphasort (a, b) { - return a > b ? 1 : a < b ? -1 : 0 -} - -Glob.prototype._mark = function (p) { - var c = this.cache[p] - var m = p - if (c) { - var isDir = c === 2 || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - this.statCache[m] = this.statCache[p] - this.cache[m] = this.cache[p] - } - } - - return m -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit("abort") -} - -Glob.prototype.pause = function () { - if (this.paused) return - if (this.sync) - this.emit("error", new Error("Can't pause/resume sync glob")) - this.paused = true - this.emit("pause") -} - -Glob.prototype.resume = function () { - if (!this.paused) return - if (this.sync) - this.emit("error", new Error("Can't pause/resume sync glob")) - this.paused = false - this.emit("resume") - this._processEmitQueue() - //process.nextTick(this.emit.bind(this, "resume")) -} - -Glob.prototype.emitMatch = function (m) { - this.log('emitMatch', m) - this._emitQueue.push(m) - this._processEmitQueue() -} - -Glob.prototype._processEmitQueue = function (m) { - this.log("pEQ paused=%j processing=%j m=%j", this.paused, - this._processingEmitQueue, m) - var done = false - while (!this._processingEmitQueue && - !this.paused) { - this._processingEmitQueue = true - var m = this._emitQueue.shift() - this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m) - if (!m) { - this.log(">processEmitQueue, falsey m") - this._processingEmitQueue = false - break - } - - if (m === this.EOF || !(this.mark && !this.stat)) { - this.log("peq: unmarked, or eof") - next.call(this, 0, false) - } else if (this.statCache[m]) { - var sc = this.statCache[m] - var exists - if (sc) - exists = sc.isDirectory() ? 2 : 1 - this.log("peq: stat cached") - next.call(this, exists, exists === 2) - } else { - this.log("peq: _stat, then next") - this._stat(m, next) - } - - function next(exists, isDir) { - this.log("next", m, exists, isDir) - var ev = m === this.EOF ? "end" : "match" - - // "end" can only happen once. - assert(!this._endEmitted) - if (ev === "end") - this._endEmitted = true - - if (exists) { - // Doesn't mean it necessarily doesn't exist, it's possible - // we just didn't check because we don't care that much, or - // this is EOF anyway. - if (isDir && !m.match(/\/$/)) { - m = m + "/" - } else if (!isDir && m.match(/\/$/)) { - m = m.replace(/\/+$/, "") - } - } - this.log("emit", ev, m) - this.emit(ev, m) - this._processingEmitQueue = false - if (done && m !== this.EOF && !this.paused) - this._processEmitQueue() - } - } - done = true -} - -Glob.prototype._process = function (pattern, depth, index, cb_) { - assert(this instanceof Glob) - - var cb = function cb (er, res) { - assert(this instanceof Glob) - if (this.paused) { - if (!this._processQueue) { - this._processQueue = [] - this.once("resume", function () { - var q = this._processQueue - this._processQueue = null - q.forEach(function (cb) { cb() }) - }) - } - this._processQueue.push(cb_.bind(this, er, res)) - } else { - cb_.call(this, er, res) - } - }.bind(this) - - if (this.aborted) return cb() - - if (depth > this.maxDepth) return cb() - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === "string") { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - prefix = pattern.join("/") - this._stat(prefix, function (exists, isDir) { - // either it's there, or it isn't. - // nothing more to do, either way. - if (exists) { - if (prefix && isAbsolute(prefix) && !this.nomount) { - if (prefix.charAt(0) === "/") { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - } - } - - if (process.platform === "win32") - prefix = prefix.replace(/\\/g, "/") - - this.matches[index] = this.matches[index] || {} - this.matches[index][prefix] = true - this.emitMatch(prefix) - } - return cb() - }) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's "absolute" like /foo/bar, - // or "relative" like "../baz" - prefix = pattern.slice(0, n) - prefix = prefix.join("/") - break - } - - // get the list of entries. - var read - if (prefix === null) read = "." - else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) { - if (!prefix || !isAbsolute(prefix)) { - prefix = path.join("/", prefix) - } - read = prefix = path.resolve(prefix) - - // if (process.platform === "win32") - // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/") - - this.log('absolute: ', prefix, this.root, pattern, read) - } else { - read = prefix - } - - this.log('readdir(%j)', read, this.cwd, this.root) - - return this._readdir(read, function (er, entries) { - if (er) { - // not a directory! - // this means that, whatever else comes after this, it can never match - return cb() - } - - // globstar is special - if (pattern[n] === minimatch.GLOBSTAR) { - // test without the globstar, and with every child both below - // and replacing the globstar. - var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ] - entries.forEach(function (e) { - if (e.charAt(0) === "." && !this.dot) return - // instead of the globstar - s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) - // below the globstar - s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n))) - }, this) - - s = s.filter(function (pattern) { - var key = gsKey(pattern) - var seen = !this._globstars[key] - this._globstars[key] = true - return seen - }, this) - - if (!s.length) - return cb() - - // now asyncForEach over this - var l = s.length - , errState = null - s.forEach(function (gsPattern) { - this._process(gsPattern, depth + 1, index, function (er) { - if (errState) return - if (er) return cb(errState = er) - if (--l <= 0) return cb() - }) - }, this) - - return - } - - // not a globstar - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = pattern[n] - var rawGlob = pattern[n]._glob - , dotOk = this.dot || rawGlob.charAt(0) === "." - - entries = entries.filter(function (e) { - return (e.charAt(0) !== "." || dotOk) && - e.match(pattern[n]) - }) - - // If n === pattern.length - 1, then there's no need for the extra stat - // *unless* the user has specified "mark" or "stat" explicitly. - // We know that they exist, since the readdir returned them. - if (n === pattern.length - 1 && - !this.mark && - !this.stat) { - entries.forEach(function (e) { - if (prefix) { - if (prefix !== "/") e = prefix + "/" + e - else e = prefix + e - } - if (e.charAt(0) === "/" && !this.nomount) { - e = path.join(this.root, e) - } - - if (process.platform === "win32") - e = e.replace(/\\/g, "/") - - this.matches[index] = this.matches[index] || {} - this.matches[index][e] = true - this.emitMatch(e) - }, this) - return cb.call(this) - } - - - // now test all the remaining entries as stand-ins for that part - // of the pattern. - var l = entries.length - , errState = null - if (l === 0) return cb() // no matches possible - entries.forEach(function (e) { - var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) - this._process(p, depth + 1, index, function (er) { - if (errState) return - if (er) return cb(errState = er) - if (--l === 0) return cb.call(this) - }) - }, this) - }) - -} - -function gsKey (pattern) { - return '**' + pattern.map(function (p) { - return (p === minimatch.GLOBSTAR) ? '**' : (''+p) - }).join('/') -} - -Glob.prototype._stat = function (f, cb) { - assert(this instanceof Glob) - var abs = f - if (f.charAt(0) === "/") { - abs = path.join(this.root, f) - } else if (this.changedCwd) { - abs = path.resolve(this.cwd, f) - } - - if (f.length > this.maxLength) { - var er = new Error("Path name too long") - er.code = "ENAMETOOLONG" - er.path = f - return this._afterStat(f, abs, cb, er) - } - - this.log('stat', [this.cwd, f, '=', abs]) - - if (!this.stat && this.cache.hasOwnProperty(f)) { - var exists = this.cache[f] - , isDir = exists && (Array.isArray(exists) || exists === 2) - if (this.sync) return cb.call(this, !!exists, isDir) - return process.nextTick(cb.bind(this, !!exists, isDir)) - } - - var stat = this.statCache[abs] - if (this.sync || stat) { - var er - try { - stat = fs.statSync(abs) - } catch (e) { - er = e - } - this._afterStat(f, abs, cb, er, stat) - } else { - fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) - } -} - -Glob.prototype._afterStat = function (f, abs, cb, er, stat) { - var exists - assert(this instanceof Glob) - - if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) { - this.log("should be ENOTDIR, fake it") - - er = new Error("ENOTDIR, not a directory '" + abs + "'") - er.path = abs - er.code = "ENOTDIR" - stat = null - } - - var emit = !this.statCache[abs] - this.statCache[abs] = stat - - if (er || !stat) { - exists = false - } else { - exists = stat.isDirectory() ? 2 : 1 - if (emit) - this.emit('stat', f, stat) - } - this.cache[f] = this.cache[f] || exists - cb.call(this, !!exists, exists === 2) -} - -Glob.prototype._readdir = function (f, cb) { - assert(this instanceof Glob) - var abs = f - if (f.charAt(0) === "/") { - abs = path.join(this.root, f) - } else if (isAbsolute(f)) { - abs = f - } else if (this.changedCwd) { - abs = path.resolve(this.cwd, f) - } - - if (f.length > this.maxLength) { - var er = new Error("Path name too long") - er.code = "ENAMETOOLONG" - er.path = f - return this._afterReaddir(f, abs, cb, er) - } - - this.log('readdir', [this.cwd, f, abs]) - if (this.cache.hasOwnProperty(f)) { - var c = this.cache[f] - if (Array.isArray(c)) { - if (this.sync) return cb.call(this, null, c) - return process.nextTick(cb.bind(this, null, c)) - } - - if (!c || c === 1) { - // either ENOENT or ENOTDIR - var code = c ? "ENOTDIR" : "ENOENT" - , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) - er.path = f - er.code = code - this.log(f, er) - if (this.sync) return cb.call(this, er) - return process.nextTick(cb.bind(this, er)) - } - - // at this point, c === 2, meaning it's a dir, but we haven't - // had to read it yet, or c === true, meaning it's *something* - // but we don't have any idea what. Need to read it, either way. - } - - if (this.sync) { - var er, entries - try { - entries = fs.readdirSync(abs) - } catch (e) { - er = e - } - return this._afterReaddir(f, abs, cb, er, entries) - } - - fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) -} - -Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { - assert(this instanceof Glob) - if (entries && !er) { - this.cache[f] = entries - // if we haven't asked to stat everything for suresies, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. This also gets us one step - // further into ELOOP territory. - if (!this.mark && !this.stat) { - entries.forEach(function (e) { - if (f === "/") e = f + e - else e = f + "/" + e - this.cache[e] = true - }, this) - } - - return cb.call(this, er, entries) - } - - // now handle errors, and cache the information - if (er) switch (er.code) { - case "ENOTDIR": // totally normal. means it *does* exist. - this.cache[f] = 1 - return cb.call(this, er) - case "ENOENT": // not terribly unusual - case "ELOOP": - case "ENAMETOOLONG": - case "UNKNOWN": - this.cache[f] = false - return cb.call(this, er) - default: // some unusual error. Treat as failure. - this.cache[f] = false - if (this.strict) this.emit("error", er) - if (!this.silent) console.error("glob error", er) - return cb.call(this, er) - } -} - -var isAbsolute = process.platform === "win32" ? absWin : absUnix - -function absWin (p) { - if (absUnix(p)) return true - // pull off the device/UNC bit from a windows path. - // from node's lib/path.js - var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/ - , result = splitDeviceRe.exec(p) - , device = result[1] || '' - , isUnc = device && device.charAt(1) !== ':' - , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute - - return isAbsolute -} - -function absUnix (p) { - return p.charAt(0) === "/" || p === "" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE deleted file mode 100644 index dea3013d..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md deleted file mode 100644 index b1c56658..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/README.md +++ /dev/null @@ -1,42 +0,0 @@ -Browser-friendly inheritance fully compatible with standard node.js -[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). - -This package exports standard `inherits` from node.js `util` module in -node environment, but also provides alternative browser-friendly -implementation through [browser -field](https://gist.github.com/shtylman/4339901). Alternative -implementation is a literal copy of standard one located in standalone -module to avoid requiring of `util`. It also has a shim for old -browsers with no `Object.create` support. - -While keeping you sure you are using standard `inherits` -implementation in node.js environment, it allows bundlers such as -[browserify](https://github.com/substack/node-browserify) to not -include full `util` package to your client code if all you need is -just `inherits` function. It worth, because browser shim for `util` -package is large and `inherits` is often the single function you need -from it. - -It's recommended to use this package instead of -`require('util').inherits` for any code that has chances to be used -not only in node.js but in browser too. - -## usage - -```js -var inherits = require('inherits'); -// then use exactly as the standard one -``` - -## note on version ~1.0 - -Version ~1.0 had completely different motivation and is not compatible -neither with 2.0 nor with standard node.js `inherits`. - -If you are using version ~1.0 and planning to switch to ~2.0, be -careful: - -* new version uses `super_` instead of `super` for referencing - superclass -* new version overwrites current prototype while old one preserves any - existing fields on it diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js deleted file mode 100644 index 29f5e24f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('util').inherits diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js deleted file mode 100644 index c1e78a75..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/inherits_browser.js +++ /dev/null @@ -1,23 +0,0 @@ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json deleted file mode 100644 index 754a1144..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "inherits", - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "version": "2.0.1", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "main": "./inherits.js", - "browser": "./inherits_browser.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/inherits" - }, - "license": "ISC", - "scripts": { - "test": "node test" - }, - "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/isaacs/inherits/issues" - }, - "_id": "inherits@2.0.1", - "dist": { - "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "_from": "inherits@2", - "_npmVersion": "1.3.8", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "homepage": "https://github.com/isaacs/inherits" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js deleted file mode 100644 index fc53012d..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/inherits/test.js +++ /dev/null @@ -1,25 +0,0 @@ -var inherits = require('./inherits.js') -var assert = require('assert') - -function test(c) { - assert(c.constructor === Child) - assert(c.constructor.super_ === Parent) - assert(Object.getPrototypeOf(c) === Child.prototype) - assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) - assert(c instanceof Child) - assert(c instanceof Parent) -} - -function Child() { - Parent.call(this) - test(this) -} - -function Parent() {} - -inherits(Child, Parent) - -var c = new Child -test(c) - -console.log('ok') diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore deleted file mode 100644 index 3c3629e6..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE deleted file mode 100644 index 05a40109..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md deleted file mode 100644 index 5b3967ea..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/README.md +++ /dev/null @@ -1,218 +0,0 @@ -# minimatch - -A minimal matching utility. - -[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch) - - -This is the matching library used internally by npm. - -Eventually, it will replace the C binding in node-glob. - -It works by converting glob expressions into JavaScript `RegExp` -objects. - -## Usage - -```javascript -var minimatch = require("minimatch") - -minimatch("bar.foo", "*.foo") // true! -minimatch("bar.foo", "*.bar") // false! -minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! -``` - -## Features - -Supports these glob features: - -* Brace Expansion -* Extended glob matching -* "Globstar" `**` matching - -See: - -* `man sh` -* `man bash` -* `man 3 fnmatch` -* `man 5 gitignore` - -## Minimatch Class - -Create a minimatch object by instanting the `minimatch.Minimatch` class. - -```javascript -var Minimatch = require("minimatch").Minimatch -var mm = new Minimatch(pattern, options) -``` - -### Properties - -* `pattern` The original pattern the minimatch object represents. -* `options` The options supplied to the constructor. -* `set` A 2-dimensional array of regexp or string expressions. - Each row in the - array corresponds to a brace-expanded pattern. Each item in the row - corresponds to a single path-part. For example, the pattern - `{a,b/c}/d` would expand to a set of patterns like: - - [ [ a, d ] - , [ b, c, d ] ] - - If a portion of the pattern doesn't have any "magic" in it - (that is, it's something like `"foo"` rather than `fo*o?`), then it - will be left as a string rather than converted to a regular - expression. - -* `regexp` Created by the `makeRe` method. A single regular expression - expressing the entire pattern. This is useful in cases where you wish - to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. -* `negate` True if the pattern is negated. -* `comment` True if the pattern is a comment. -* `empty` True if the pattern is `""`. - -### Methods - -* `makeRe` Generate the `regexp` member if necessary, and return it. - Will return `false` if the pattern is invalid. -* `match(fname)` Return true if the filename matches the pattern, or - false otherwise. -* `matchOne(fileArray, patternArray, partial)` Take a `/`-split - filename, and match it against a single row in the `regExpSet`. This - method is mainly for internal use, but is exposed so that it can be - used by a glob-walker that needs to avoid excessive filesystem calls. - -All other methods are internal, and will be called as necessary. - -## Functions - -The top-level exported function has a `cache` property, which is an LRU -cache set to store 100 items. So, calling these methods repeatedly -with the same pattern and options will use the same Minimatch object, -saving the cost of parsing it multiple times. - -### minimatch(path, pattern, options) - -Main export. Tests a path against the pattern using the options. - -```javascript -var isJS = minimatch(file, "*.js", { matchBase: true }) -``` - -### minimatch.filter(pattern, options) - -Returns a function that tests its -supplied argument, suitable for use with `Array.filter`. Example: - -```javascript -var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) -``` - -### minimatch.match(list, pattern, options) - -Match against the list of -files, in the style of fnmatch or glob. If nothing is matched, and -options.nonull is set, then return a list containing the pattern itself. - -```javascript -var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) -``` - -### minimatch.makeRe(pattern, options) - -Make a regular expression object from the pattern. - -## Options - -All options are `false` by default. - -### debug - -Dump a ton of stuff to stderr. - -### nobrace - -Do not expand `{a,b}` and `{1..3}` brace sets. - -### noglobstar - -Disable `**` matching against multiple folder names. - -### dot - -Allow patterns to match filenames starting with a period, even if -the pattern does not explicitly have a period in that spot. - -Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` -is set. - -### noext - -Disable "extglob" style patterns like `+(a|b)`. - -### nocase - -Perform a case-insensitive match. - -### nonull - -When a match is not found by `minimatch.match`, return a list containing -the pattern itself if this option is set. When not set, an empty list -is returned if there are no matches. - -### matchBase - -If set, then patterns without slashes will be matched -against the basename of the path if it contains slashes. For example, -`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. - -### nocomment - -Suppress the behavior of treating `#` at the start of a pattern as a -comment. - -### nonegate - -Suppress the behavior of treating a leading `!` character as negation. - -### flipNegate - -Returns from negate expressions the same as if they were not negated. -(Ie, true on a hit, false on a miss.) - - -## Comparisons to other fnmatch/glob implementations - -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between minimatch and other -implementations, and are intentional. - -If the pattern starts with a `!` character, then it is negated. Set the -`nonegate` flag to suppress this behavior, and treat leading `!` -characters normally. This is perhaps relevant if you wish to start the -pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` -characters at the start of a pattern will negate the pattern multiple -times. - -If a pattern starts with `#`, then it is treated as a comment, and -will not match anything. Use `\#` to match a literal `#` at the -start of a line, or set the `nocomment` flag to suppress this behavior. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.1, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then minimatch.match returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js deleted file mode 100644 index 45396789..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,1061 +0,0 @@ -;(function (require, exports, module, platform) { - -if (module) module.exports = minimatch -else exports.minimatch = minimatch - -if (!require) { - require = function (id) { - switch (id) { - case "sigmund": return function sigmund (obj) { - return JSON.stringify(obj) - } - case "path": return { basename: function (f) { - f = f.split(/[\/\\]/) - var e = f.pop() - if (!e) e = f.pop() - return e - }} - case "lru-cache": return function LRUCache () { - // not quite an LRU, but still space-limited. - var cache = {} - var cnt = 0 - this.set = function (k, v) { - cnt ++ - if (cnt >= 100) cache = {} - cache[k] = v - } - this.get = function (k) { return cache[k] } - } - } - } -} - -minimatch.Minimatch = Minimatch - -var LRU = require("lru-cache") - , cache = minimatch.cache = new LRU({max: 100}) - , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} - , sigmund = require("sigmund") - -var path = require("path") - // any single thing other than / - // don't need to escape / when using new RegExp() - , qmark = "[^/]" - - // * => any number of characters - , star = qmark + "*?" - - // ** when dots are allowed. Anything goes, except .. and . - // not (^ or / followed by one or two dots followed by $ or /), - // followed by anything, any number of times. - , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" - - // not a ^ or / followed by a dot, - // followed by anything, any number of times. - , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" - - // characters that need to be escaped in RegExp. - , reSpecials = charSet("().*{}+?[]^$\\!") - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split("").reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - - -function minimatch (p, pattern, options) { - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required") - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === "#") { - return false - } - - // "" only matches "" - if (pattern.trim() === "") return p === "" - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options, cache) - } - - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required") - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. - if (platform === "win32") { - pattern = pattern.split("\\").join("/") - } - - // lru storage. - // these things aren't particularly big, but walking down the string - // and turning it into a regexp can get pretty costly. - var cacheKey = pattern + "\n" + sigmund(options) - var cached = minimatch.cache.get(cacheKey) - if (cached) return cached - minimatch.cache.set(cacheKey, this) - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function() {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === "#") { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return -1 === s.indexOf(false) - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - , negate = false - , options = this.options - , negateOffset = 0 - - if (options.nonegate) return - - for ( var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === "!" - ; i ++) { - negate = !negate - negateOffset ++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return new Minimatch(pattern, options).braceExpand() -} - -Minimatch.prototype.braceExpand = braceExpand -function braceExpand (pattern, options) { - options = options || this.options - pattern = typeof pattern === "undefined" - ? this.pattern : pattern - - if (typeof pattern === "undefined") { - throw new Error("undefined pattern") - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - var escaping = false - - // examples and comments refer to this crazy pattern: - // a{b,c{d,e},{f,g}h}x{y,z} - // expected: - // abxy - // abxz - // acdxy - // acdxz - // acexy - // acexz - // afhxy - // afhxz - // aghxy - // aghxz - - // everything before the first \{ is just a prefix. - // So, we pluck that off, and work with the rest, - // and then prepend it to everything we find. - if (pattern.charAt(0) !== "{") { - this.debug(pattern) - var prefix = null - for (var i = 0, l = pattern.length; i < l; i ++) { - var c = pattern.charAt(i) - this.debug(i, c) - if (c === "\\") { - escaping = !escaping - } else if (c === "{" && !escaping) { - prefix = pattern.substr(0, i) - break - } - } - - // actually no sets, all { were escaped. - if (prefix === null) { - this.debug("no sets") - return [pattern] - } - - var tail = braceExpand.call(this, pattern.substr(i), options) - return tail.map(function (t) { - return prefix + t - }) - } - - // now we have something like: - // {b,c{d,e},{f,g}h}x{y,z} - // walk through the set, expanding each part, until - // the set ends. then, we'll expand the suffix. - // If the set only has a single member, then'll put the {} back - - // first, handle numeric sets, since they're easier - var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/) - if (numset) { - this.debug("numset", numset[1], numset[2]) - var suf = braceExpand.call(this, pattern.substr(numset[0].length), options) - , start = +numset[1] - , end = +numset[2] - , inc = start > end ? -1 : 1 - , set = [] - for (var i = start; i != (end + inc); i += inc) { - // append all the suffixes - for (var ii = 0, ll = suf.length; ii < ll; ii ++) { - set.push(i + suf[ii]) - } - } - return set - } - - // ok, walk through the set - // We hope, somewhat optimistically, that there - // will be a } at the end. - // If the closing brace isn't found, then the pattern is - // interpreted as braceExpand("\\" + pattern) so that - // the leading \{ will be interpreted literally. - var i = 1 // skip the \{ - , depth = 1 - , set = [] - , member = "" - , sawEnd = false - , escaping = false - - function addMember () { - set.push(member) - member = "" - } - - this.debug("Entering for") - FOR: for (i = 1, l = pattern.length; i < l; i ++) { - var c = pattern.charAt(i) - this.debug("", i, c) - - if (escaping) { - escaping = false - member += "\\" + c - } else { - switch (c) { - case "\\": - escaping = true - continue - - case "{": - depth ++ - member += "{" - continue - - case "}": - depth -- - // if this closes the actual set, then we're done - if (depth === 0) { - addMember() - // pluck off the close-brace - i ++ - break FOR - } else { - member += c - continue - } - - case ",": - if (depth === 1) { - addMember() - } else { - member += c - } - continue - - default: - member += c - continue - } // switch - } // else - } // for - - // now we've either finished the set, and the suffix is - // pattern.substr(i), or we have *not* closed the set, - // and need to escape the leading brace - if (depth !== 0) { - this.debug("didn't close", pattern) - return braceExpand.call(this, "\\" + pattern, options) - } - - // x{y,z} -> ["xy", "xz"] - this.debug("set", set) - this.debug("suffix", pattern.substr(i)) - var suf = braceExpand.call(this, pattern.substr(i), options) - // ["b", "c{d,e}","{f,g}h"] -> - // [["b"], ["cd", "ce"], ["fh", "gh"]] - var addBraces = set.length === 1 - this.debug("set pre-expanded", set) - set = set.map(function (p) { - return braceExpand.call(this, p, options) - }, this) - this.debug("set expanded", set) - - - // [["b"], ["cd", "ce"], ["fh", "gh"]] -> - // ["b", "cd", "ce", "fh", "gh"] - set = set.reduce(function (l, r) { - return l.concat(r) - }) - - if (addBraces) { - set = set.map(function (s) { - return "{" + s + "}" - }) - } - - // now attach the suffixes. - var ret = [] - for (var i = 0, l = set.length; i < l; i ++) { - for (var ii = 0, ll = suf.length; ii < ll; ii ++) { - ret.push(set[i] + suf[ii]) - } - } - return ret -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === "**") return GLOBSTAR - if (pattern === "") return "" - - var re = "" - , hasMagic = !!options.nocase - , escaping = false - // ? => one single character - , patternListStack = [] - , plType - , stateChar - , inClass = false - , reClassStart = -1 - , classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - , patternStart = pattern.charAt(0) === "." ? "" // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" - : "(?!\\.)" - , self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case "*": - re += star - hasMagic = true - break - case "?": - re += qmark - hasMagic = true - break - default: - re += "\\"+stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for ( var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i ++ ) { - - this.debug("%s\t%s %s %j", pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += "\\" + c - escaping = false - continue - } - - SWITCH: switch (c) { - case "/": - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case "\\": - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case "?": - case "*": - case "+": - case "@": - case "!": - this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === "!" && i === classStart + 1) c = "^" - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case "(": - if (inClass) { - re += "(" - continue - } - - if (!stateChar) { - re += "\\(" - continue - } - - plType = stateChar - patternListStack.push({ type: plType - , start: i - 1 - , reStart: re.length }) - // negation is (?:(?!js)[^/]*) - re += stateChar === "!" ? "(?:(?!" : "(?:" - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ")": - if (inClass || !patternListStack.length) { - re += "\\)" - continue - } - - clearStateChar() - hasMagic = true - re += ")" - plType = patternListStack.pop().type - // negation is (?:(?!js)[^/]*) - // The others are (?:) - switch (plType) { - case "!": - re += "[^/]*?)" - break - case "?": - case "+": - case "*": re += plType - case "@": break // the default anyway - } - continue - - case "|": - if (inClass || !patternListStack.length || escaping) { - re += "\\|" - escaping = false - continue - } - - clearStateChar() - re += "|" - continue - - // these are mostly the same in regexp and glob - case "[": - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += "\\" + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case "]": - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += "\\" + c - escaping = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === "^" && inClass)) { - re += "\\" - } - - re += c - - } // switch - } // for - - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - var cs = pattern.substr(classStart + 1) - , sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + "\\[" + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - var pl - while (pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + 3) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = "\\" - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + "|" - }) - - this.debug("tail=%j\n %s", tail, tail) - var t = pl.type === "*" ? star - : pl.type === "?" ? qmark - : "\\" + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) - + t + "\\(" - + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += "\\\\" - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case ".": - case "[": - case "(": addPatternStart = true - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== "" && hasMagic) re = "(?=.)" + re - - if (addPatternStart) re = patternStart + re - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [ re, hasMagic ] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? "i" : "" - , regExp = new RegExp("^" + re + "$", flags) - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) return this.regexp = false - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - , flags = options.nocase ? "i" : "" - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === "string") ? regExpEscape(p) - : p._src - }).join("\\\/") - }).join("|") - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = "^(?:" + re + ")$" - - // can match anything, as long as it's not this. - if (this.negate) re = "^(?!" + re + ").*$" - - try { - return this.regexp = new RegExp(re, flags) - } catch (ex) { - return this.regexp = false - } -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug("match", f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === "" - - if (f === "/" && partial) return true - - var options = this.options - - // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. - if (platform === "win32") { - f = f.split("\\").join("/") - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, "split", f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, "set", set) - - // Find the basename of the path by looking for the last non-empty segment - var filename; - for (var i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (var i = 0, l = set.length; i < l; i ++) { - var pattern = set[i], file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug("matchOne", - { "this": this - , file: file - , pattern: pattern }) - - this.debug("matchOne", file.length, pattern.length) - - for ( var fi = 0 - , pi = 0 - , fl = file.length - , pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi ++, pi ++ ) { - - this.debug("matchOne loop") - var p = pattern[pi] - , f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - , pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for ( ; fi < fl; fi ++) { - if (file[fi] === "." || file[fi] === ".." || - (!options.dot && file[fi].charAt(0) === ".")) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - WHILE: while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', - file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === "." || swallowee === ".." || - (!options.dot && swallowee.charAt(0) === ".")) { - this.debug("dot detected!", file, fr, pattern, pr) - break WHILE - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr ++ - } - } - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug("\n>>> no match, partial?", file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === "string") { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug("string match", p, f, hit) - } else { - hit = f.match(p) - this.debug("pattern match", p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === "") - return emptyFileEnd - } - - // should be unreachable. - throw new Error("wtf?") -} - - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, "$1") -} - - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") -} - -})( typeof require === "function" ? require : null, - this, - typeof module === "object" ? module : null, - typeof process === "object" ? process.platform : "win32" - ) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore deleted file mode 100644 index 07e6e472..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS deleted file mode 100644 index 4a0bc503..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +++ /dev/null @@ -1,14 +0,0 @@ -# Authors, sorted by whether or not they are me -Isaac Z. Schlueter -Brian Cottingham -Carlos Brito Lage -Jesse Dailey -Kevin O'Hara -Marco Rogers -Mark Cavage -Marko Mikulicic -Nathan Rajlich -Satheesh Natesan -Trent Mick -ashleybrener -n4kz diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE deleted file mode 100644 index 05a40109..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md deleted file mode 100644 index 03ee0f98..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# lru cache - -A cache object that deletes the least-recently-used items. - -## Usage: - -```javascript -var LRU = require("lru-cache") - , options = { max: 500 - , length: function (n) { return n * 2 } - , dispose: function (key, n) { n.close() } - , maxAge: 1000 * 60 * 60 } - , cache = LRU(options) - , otherCache = LRU(50) // sets just the max size - -cache.set("key", "value") -cache.get("key") // "value" - -cache.reset() // empty the cache -``` - -If you put more stuff in it, then items will fall out. - -If you try to put an oversized thing in it, then it'll fall out right -away. - -## Options - -* `max` The maximum size of the cache, checked by applying the length - function to all values in the cache. Not setting this is kind of - silly, since that's the whole purpose of this lib, but it defaults - to `Infinity`. -* `maxAge` Maximum age in ms. Items are not pro-actively pruned out - as they age, but if you try to get an item that is too old, it'll - drop it and return undefined instead of giving it to you. -* `length` Function that is used to calculate the length of stored - items. If you're storing strings or buffers, then you probably want - to do something like `function(n){return n.length}`. The default is - `function(n){return 1}`, which is fine if you want to store `n` - like-sized things. -* `dispose` Function that is called on items when they are dropped - from the cache. This can be handy if you want to close file - descriptors or do other cleanup tasks when items are no longer - accessible. Called with `key, value`. It's called *before* - actually removing the item from the internal cache, so if you want - to immediately put it back in, you'll have to do that in a - `nextTick` or `setTimeout` callback or it won't do anything. -* `stale` By default, if you set a `maxAge`, it'll only actually pull - stale items out of the cache when you `get(key)`. (That is, it's - not pre-emptively doing a `setTimeout` or anything.) If you set - `stale:true`, it'll return the stale value before deleting it. If - you don't set this, then it'll return `undefined` when you try to - get a stale entry, as if it had already been deleted. - -## API - -* `set(key, value)` -* `get(key) => value` - - Both of these will update the "recently used"-ness of the key. - They do what you think. - -* `peek(key)` - - Returns the key value (or `undefined` if not found) without - updating the "recently used"-ness of the key. - - (If you find yourself using this a lot, you *might* be using the - wrong sort of data structure, but there are some use cases where - it's handy.) - -* `del(key)` - - Deletes a key out of the cache. - -* `reset()` - - Clear the cache entirely, throwing away all values. - -* `has(key)` - - Check if a key is in the cache, without updating the recent-ness - or deleting it for being stale. - -* `forEach(function(value,key,cache), [thisp])` - - Just like `Array.prototype.forEach`. Iterates over all the keys - in the cache, in order of recent-ness. (Ie, more recently used - items are iterated over first.) - -* `keys()` - - Return an array of the keys in the cache. - -* `values()` - - Return an array of the values in the cache. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js deleted file mode 100644 index d1d13817..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +++ /dev/null @@ -1,252 +0,0 @@ -;(function () { // closure for web browsers - -if (typeof module === 'object' && module.exports) { - module.exports = LRUCache -} else { - // just set the global for non-node platforms. - this.LRUCache = LRUCache -} - -function hOP (obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key) -} - -function naiveLength () { return 1 } - -function LRUCache (options) { - if (!(this instanceof LRUCache)) - return new LRUCache(options) - - if (typeof options === 'number') - options = { max: options } - - if (!options) - options = {} - - this._max = options.max - // Kind of weird to have a default max of Infinity, but oh well. - if (!this._max || !(typeof this._max === "number") || this._max <= 0 ) - this._max = Infinity - - this._lengthCalculator = options.length || naiveLength - if (typeof this._lengthCalculator !== "function") - this._lengthCalculator = naiveLength - - this._allowStale = options.stale || false - this._maxAge = options.maxAge || null - this._dispose = options.dispose - this.reset() -} - -// resize the cache when the max changes. -Object.defineProperty(LRUCache.prototype, "max", - { set : function (mL) { - if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity - this._max = mL - if (this._length > this._max) trim(this) - } - , get : function () { return this._max } - , enumerable : true - }) - -// resize the cache when the lengthCalculator changes. -Object.defineProperty(LRUCache.prototype, "lengthCalculator", - { set : function (lC) { - if (typeof lC !== "function") { - this._lengthCalculator = naiveLength - this._length = this._itemCount - for (var key in this._cache) { - this._cache[key].length = 1 - } - } else { - this._lengthCalculator = lC - this._length = 0 - for (var key in this._cache) { - this._cache[key].length = this._lengthCalculator(this._cache[key].value) - this._length += this._cache[key].length - } - } - - if (this._length > this._max) trim(this) - } - , get : function () { return this._lengthCalculator } - , enumerable : true - }) - -Object.defineProperty(LRUCache.prototype, "length", - { get : function () { return this._length } - , enumerable : true - }) - - -Object.defineProperty(LRUCache.prototype, "itemCount", - { get : function () { return this._itemCount } - , enumerable : true - }) - -LRUCache.prototype.forEach = function (fn, thisp) { - thisp = thisp || this - var i = 0; - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - i++ - var hit = this._lruList[k] - if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { - del(this, hit) - if (!this._allowStale) hit = undefined - } - if (hit) { - fn.call(thisp, hit.value, hit.key, this) - } - } -} - -LRUCache.prototype.keys = function () { - var keys = new Array(this._itemCount) - var i = 0 - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - var hit = this._lruList[k] - keys[i++] = hit.key - } - return keys -} - -LRUCache.prototype.values = function () { - var values = new Array(this._itemCount) - var i = 0 - for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { - var hit = this._lruList[k] - values[i++] = hit.value - } - return values -} - -LRUCache.prototype.reset = function () { - if (this._dispose && this._cache) { - for (var k in this._cache) { - this._dispose(k, this._cache[k].value) - } - } - - this._cache = Object.create(null) // hash of items by key - this._lruList = Object.create(null) // list of items in order of use recency - this._mru = 0 // most recently used - this._lru = 0 // least recently used - this._length = 0 // number of items in the list - this._itemCount = 0 -} - -// Provided for debugging/dev purposes only. No promises whatsoever that -// this API stays stable. -LRUCache.prototype.dump = function () { - return this._cache -} - -LRUCache.prototype.dumpLru = function () { - return this._lruList -} - -LRUCache.prototype.set = function (key, value) { - if (hOP(this._cache, key)) { - // dispose of the old one before overwriting - if (this._dispose) this._dispose(key, this._cache[key].value) - if (this._maxAge) this._cache[key].now = Date.now() - this._cache[key].value = value - this.get(key) - return true - } - - var len = this._lengthCalculator(value) - var age = this._maxAge ? Date.now() : 0 - var hit = new Entry(key, value, this._mru++, len, age) - - // oversized objects fall out of cache automatically. - if (hit.length > this._max) { - if (this._dispose) this._dispose(key, value) - return false - } - - this._length += hit.length - this._lruList[hit.lu] = this._cache[key] = hit - this._itemCount ++ - - if (this._length > this._max) trim(this) - return true -} - -LRUCache.prototype.has = function (key) { - if (!hOP(this._cache, key)) return false - var hit = this._cache[key] - if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { - return false - } - return true -} - -LRUCache.prototype.get = function (key) { - return get(this, key, true) -} - -LRUCache.prototype.peek = function (key) { - return get(this, key, false) -} - -LRUCache.prototype.pop = function () { - var hit = this._lruList[this._lru] - del(this, hit) - return hit || null -} - -LRUCache.prototype.del = function (key) { - del(this, this._cache[key]) -} - -function get (self, key, doUse) { - var hit = self._cache[key] - if (hit) { - if (self._maxAge && (Date.now() - hit.now > self._maxAge)) { - del(self, hit) - if (!self._allowStale) hit = undefined - } else { - if (doUse) use(self, hit) - } - if (hit) hit = hit.value - } - return hit -} - -function use (self, hit) { - shiftLU(self, hit) - hit.lu = self._mru ++ - self._lruList[hit.lu] = hit -} - -function trim (self) { - while (self._lru < self._mru && self._length > self._max) - del(self, self._lruList[self._lru]) -} - -function shiftLU (self, hit) { - delete self._lruList[ hit.lu ] - while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++ -} - -function del (self, hit) { - if (hit) { - if (self._dispose) self._dispose(hit.key, hit.value) - self._length -= hit.length - self._itemCount -- - delete self._cache[ hit.key ] - shiftLU(self, hit) - } -} - -// classy, since V8 prefers predictable objects. -function Entry (key, value, lu, length, now) { - this.key = key - this.value = value - this.lu = lu - this.length = length - this.now = now -} - -})() diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json deleted file mode 100644 index 2474729b..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "lru-cache", - "description": "A cache object that deletes the least-recently-used items.", - "version": "2.5.0", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "scripts": { - "test": "tap test --gc" - }, - "main": "lib/lru-cache.js", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-lru-cache.git" - }, - "devDependencies": { - "tap": "", - "weak": "" - }, - "license": { - "type": "MIT", - "url": "http://github.com/isaacs/node-lru-cache/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/node-lru-cache/issues" - }, - "homepage": "https://github.com/isaacs/node-lru-cache", - "_id": "lru-cache@2.5.0", - "dist": { - "shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb", - "tarball": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz" - }, - "_from": "lru-cache@2", - "_npmVersion": "1.3.15", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {}, - "_shasum": "d82388ae9c960becbea0c73bb9eb79b6c6ce9aeb", - "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js deleted file mode 100644 index f72697c4..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js +++ /dev/null @@ -1,369 +0,0 @@ -var test = require("tap").test - , LRU = require("../") - -test("basic", function (t) { - var cache = new LRU({max: 10}) - cache.set("key", "value") - t.equal(cache.get("key"), "value") - t.equal(cache.get("nada"), undefined) - t.equal(cache.length, 1) - t.equal(cache.max, 10) - t.end() -}) - -test("least recently set", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), "B") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("lru recently gotten", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - cache.get("a") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), undefined) - t.equal(cache.get("a"), "A") - t.end() -}) - -test("del", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.del("a") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("max", function (t) { - var cache = new LRU(3) - - // test changing the max, verify that the LRU items get dropped. - cache.max = 100 - for (var i = 0; i < 100; i ++) cache.set(i, i) - t.equal(cache.length, 100) - for (var i = 0; i < 100; i ++) { - t.equal(cache.get(i), i) - } - cache.max = 3 - t.equal(cache.length, 3) - for (var i = 0; i < 97; i ++) { - t.equal(cache.get(i), undefined) - } - for (var i = 98; i < 100; i ++) { - t.equal(cache.get(i), i) - } - - // now remove the max restriction, and try again. - cache.max = "hello" - for (var i = 0; i < 100; i ++) cache.set(i, i) - t.equal(cache.length, 100) - for (var i = 0; i < 100; i ++) { - t.equal(cache.get(i), i) - } - // should trigger an immediate resize - cache.max = 3 - t.equal(cache.length, 3) - for (var i = 0; i < 97; i ++) { - t.equal(cache.get(i), undefined) - } - for (var i = 98; i < 100; i ++) { - t.equal(cache.get(i), i) - } - t.end() -}) - -test("reset", function (t) { - var cache = new LRU(10) - cache.set("a", "A") - cache.set("b", "B") - cache.reset() - t.equal(cache.length, 0) - t.equal(cache.max, 10) - t.equal(cache.get("a"), undefined) - t.equal(cache.get("b"), undefined) - t.end() -}) - - -// Note: `.dump()` is a debugging tool only. No guarantees are made -// about the format/layout of the response. -test("dump", function (t) { - var cache = new LRU(10) - var d = cache.dump(); - t.equal(Object.keys(d).length, 0, "nothing in dump for empty cache") - cache.set("a", "A") - var d = cache.dump() // { a: { key: "a", value: "A", lu: 0 } } - t.ok(d.a) - t.equal(d.a.key, "a") - t.equal(d.a.value, "A") - t.equal(d.a.lu, 0) - - cache.set("b", "B") - cache.get("b") - d = cache.dump() - t.ok(d.b) - t.equal(d.b.key, "b") - t.equal(d.b.value, "B") - t.equal(d.b.lu, 2) - - t.end() -}) - - -test("basic with weighed length", function (t) { - var cache = new LRU({ - max: 100, - length: function (item) { return item.size } - }) - cache.set("key", {val: "value", size: 50}) - t.equal(cache.get("key").val, "value") - t.equal(cache.get("nada"), undefined) - t.equal(cache.lengthCalculator(cache.get("key")), 50) - t.equal(cache.length, 50) - t.equal(cache.max, 100) - t.end() -}) - - -test("weighed length item too large", function (t) { - var cache = new LRU({ - max: 10, - length: function (item) { return item.size } - }) - t.equal(cache.max, 10) - - // should fall out immediately - cache.set("key", {val: "value", size: 50}) - - t.equal(cache.length, 0) - t.equal(cache.get("key"), undefined) - t.end() -}) - -test("least recently set with weighed length", function (t) { - var cache = new LRU({ - max:8, - length: function (item) { return item.length } - }) - cache.set("a", "A") - cache.set("b", "BB") - cache.set("c", "CCC") - cache.set("d", "DDDD") - t.equal(cache.get("d"), "DDDD") - t.equal(cache.get("c"), "CCC") - t.equal(cache.get("b"), undefined) - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("lru recently gotten with weighed length", function (t) { - var cache = new LRU({ - max: 8, - length: function (item) { return item.length } - }) - cache.set("a", "A") - cache.set("b", "BB") - cache.set("c", "CCC") - cache.get("a") - cache.get("b") - cache.set("d", "DDDD") - t.equal(cache.get("c"), undefined) - t.equal(cache.get("d"), "DDDD") - t.equal(cache.get("b"), "BB") - t.equal(cache.get("a"), "A") - t.end() -}) - -test("set returns proper booleans", function(t) { - var cache = new LRU({ - max: 5, - length: function (item) { return item.length } - }) - - t.equal(cache.set("a", "A"), true) - - // should return false for max exceeded - t.equal(cache.set("b", "donuts"), false) - - t.equal(cache.set("b", "B"), true) - t.equal(cache.set("c", "CCCC"), true) - t.end() -}) - -test("drop the old items", function(t) { - var cache = new LRU({ - max: 5, - maxAge: 50 - }) - - cache.set("a", "A") - - setTimeout(function () { - cache.set("b", "b") - t.equal(cache.get("a"), "A") - }, 25) - - setTimeout(function () { - cache.set("c", "C") - // timed out - t.notOk(cache.get("a")) - }, 60) - - setTimeout(function () { - t.notOk(cache.get("b")) - t.equal(cache.get("c"), "C") - }, 90) - - setTimeout(function () { - t.notOk(cache.get("c")) - t.end() - }, 155) -}) - -test("disposal function", function(t) { - var disposed = false - var cache = new LRU({ - max: 1, - dispose: function (k, n) { - disposed = n - } - }) - - cache.set(1, 1) - cache.set(2, 2) - t.equal(disposed, 1) - cache.set(3, 3) - t.equal(disposed, 2) - cache.reset() - t.equal(disposed, 3) - t.end() -}) - -test("disposal function on too big of item", function(t) { - var disposed = false - var cache = new LRU({ - max: 1, - length: function (k) { - return k.length - }, - dispose: function (k, n) { - disposed = n - } - }) - var obj = [ 1, 2 ] - - t.equal(disposed, false) - cache.set("obj", obj) - t.equal(disposed, obj) - t.end() -}) - -test("has()", function(t) { - var cache = new LRU({ - max: 1, - maxAge: 10 - }) - - cache.set('foo', 'bar') - t.equal(cache.has('foo'), true) - cache.set('blu', 'baz') - t.equal(cache.has('foo'), false) - t.equal(cache.has('blu'), true) - setTimeout(function() { - t.equal(cache.has('blu'), false) - t.end() - }, 15) -}) - -test("stale", function(t) { - var cache = new LRU({ - maxAge: 10, - stale: true - }) - - cache.set('foo', 'bar') - t.equal(cache.get('foo'), 'bar') - t.equal(cache.has('foo'), true) - setTimeout(function() { - t.equal(cache.has('foo'), false) - t.equal(cache.get('foo'), 'bar') - t.equal(cache.get('foo'), undefined) - t.end() - }, 15) -}) - -test("lru update via set", function(t) { - var cache = LRU({ max: 2 }); - - cache.set('foo', 1); - cache.set('bar', 2); - cache.del('bar'); - cache.set('baz', 3); - cache.set('qux', 4); - - t.equal(cache.get('foo'), undefined) - t.equal(cache.get('bar'), undefined) - t.equal(cache.get('baz'), 3) - t.equal(cache.get('qux'), 4) - t.end() -}) - -test("least recently set w/ peek", function (t) { - var cache = new LRU(2) - cache.set("a", "A") - cache.set("b", "B") - t.equal(cache.peek("a"), "A") - cache.set("c", "C") - t.equal(cache.get("c"), "C") - t.equal(cache.get("b"), "B") - t.equal(cache.get("a"), undefined) - t.end() -}) - -test("pop the least used item", function (t) { - var cache = new LRU(3) - , last - - cache.set("a", "A") - cache.set("b", "B") - cache.set("c", "C") - - t.equal(cache.length, 3) - t.equal(cache.max, 3) - - // Ensure we pop a, c, b - cache.get("b", "B") - - last = cache.pop() - t.equal(last.key, "a") - t.equal(last.value, "A") - t.equal(cache.length, 2) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last.key, "c") - t.equal(last.value, "C") - t.equal(cache.length, 1) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last.key, "b") - t.equal(last.value, "B") - t.equal(cache.length, 0) - t.equal(cache.max, 3) - - last = cache.pop() - t.equal(last, null) - t.equal(cache.length, 0) - t.equal(cache.max, 3) - - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js deleted file mode 100644 index eefb80d9..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +++ /dev/null @@ -1,52 +0,0 @@ -var test = require('tap').test -var LRU = require('../') - -test('forEach', function (t) { - var l = new LRU(5) - for (var i = 0; i < 10; i ++) { - l.set(i.toString(), i.toString(2)) - } - - var i = 9 - l.forEach(function (val, key, cache) { - t.equal(cache, l) - t.equal(key, i.toString()) - t.equal(val, i.toString(2)) - i -= 1 - }) - - // get in order of most recently used - l.get(6) - l.get(8) - - var order = [ 8, 6, 9, 7, 5 ] - var i = 0 - - l.forEach(function (val, key, cache) { - var j = order[i ++] - t.equal(cache, l) - t.equal(key, j.toString()) - t.equal(val, j.toString(2)) - }) - - t.end() -}) - -test('keys() and values()', function (t) { - var l = new LRU(5) - for (var i = 0; i < 10; i ++) { - l.set(i.toString(), i.toString(2)) - } - - t.similar(l.keys(), ['9', '8', '7', '6', '5']) - t.similar(l.values(), ['1001', '1000', '111', '110', '101']) - - // get in order of most recently used - l.get(6) - l.get(8) - - t.similar(l.keys(), ['8', '6', '9', '7', '5']) - t.similar(l.values(), ['1000', '110', '1001', '111', '101']) - - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js deleted file mode 100644 index 7af45b02..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node --expose_gc - -var weak = require('weak'); -var test = require('tap').test -var LRU = require('../') -var l = new LRU({ max: 10 }) -var refs = 0 -function X() { - refs ++ - weak(this, deref) -} - -function deref() { - refs -- -} - -test('no leaks', function (t) { - // fill up the cache - for (var i = 0; i < 100; i++) { - l.set(i, new X); - // throw some gets in there, too. - if (i % 2 === 0) - l.get(i / 2) - } - - gc() - - var start = process.memoryUsage() - - // capture the memory - var startRefs = refs - - // do it again, but more - for (var i = 0; i < 10000; i++) { - l.set(i, new X); - // throw some gets in there, too. - if (i % 2 === 0) - l.get(i / 2) - } - - gc() - - var end = process.memoryUsage() - t.equal(refs, startRefs, 'no leaky refs') - - console.error('start: %j\n' + - 'end: %j', start, end); - t.pass(); - t.end(); -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE deleted file mode 100644 index 0c44ae71..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) Isaac Z. Schlueter ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. 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 AUTHOR 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 AUTHOR 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/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md deleted file mode 100644 index 7e365129..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# sigmund - -Quick and dirty signatures for Objects. - -This is like a much faster `deepEquals` comparison, which returns a -string key suitable for caches and the like. - -## Usage - -```javascript -function doSomething (someObj) { - var key = sigmund(someObj, maxDepth) // max depth defaults to 10 - var cached = cache.get(key) - if (cached) return cached) - - var result = expensiveCalculation(someObj) - cache.set(key, result) - return result -} -``` - -The resulting key will be as unique and reproducible as calling -`JSON.stringify` or `util.inspect` on the object, but is much faster. -In order to achieve this speed, some differences are glossed over. -For example, the object `{0:'foo'}` will be treated identically to the -array `['foo']`. - -Also, just as there is no way to summon the soul from the scribblings -of a cocain-addled psychoanalyst, there is no way to revive the object -from the signature string that sigmund gives you. In fact, it's -barely even readable. - -As with `sys.inspect` and `JSON.stringify`, larger objects will -produce larger signature strings. - -Because sigmund is a bit less strict than the more thorough -alternatives, the strings will be shorter, and also there is a -slightly higher chance for collisions. For example, these objects -have the same signature: - - var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} - var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} - -Like a good Freudian, sigmund is most effective when you already have -some understanding of what you're looking for. It can help you help -yourself, but you must be willing to do some work as well. - -Cycles are handled, and cyclical objects are silently omitted (though -the key is included in the signature output.) - -The second argument is the maximum depth, which defaults to 10, -because that is the maximum object traversal depth covered by most -insurance carriers. diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js deleted file mode 100644 index 5acfd6d9..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js +++ /dev/null @@ -1,283 +0,0 @@ -// different ways to id objects -// use a req/res pair, since it's crazy deep and cyclical - -// sparseFE10 and sigmund are usually pretty close, which is to be expected, -// since they are essentially the same algorithm, except that sigmund handles -// regular expression objects properly. - - -var http = require('http') -var util = require('util') -var sigmund = require('./sigmund.js') -var sreq, sres, creq, cres, test - -http.createServer(function (q, s) { - sreq = q - sres = s - sres.end('ok') - this.close(function () { setTimeout(function () { - start() - }, 200) }) -}).listen(1337, function () { - creq = http.get({ port: 1337 }) - creq.on('response', function (s) { cres = s }) -}) - -function start () { - test = [sreq, sres, creq, cres] - // test = sreq - // sreq.sres = sres - // sreq.creq = creq - // sreq.cres = cres - - for (var i in exports.compare) { - console.log(i) - var hash = exports.compare[i]() - console.log(hash) - console.log(hash.length) - console.log('') - } - - require('bench').runMain() -} - -function customWs (obj, md, d) { - d = d || 0 - var to = typeof obj - if (to === 'undefined' || to === 'function' || to === null) return '' - if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '') - - if (Array.isArray(obj)) { - return obj.map(function (i, _, __) { - return customWs(i, md, d + 1) - }).reduce(function (a, b) { return a + b }, '') - } - - var keys = Object.keys(obj) - return keys.map(function (k, _, __) { - return k + ':' + customWs(obj[k], md, d + 1) - }).reduce(function (a, b) { return a + b }, '') -} - -function custom (obj, md, d) { - d = d || 0 - var to = typeof obj - if (to === 'undefined' || to === 'function' || to === null) return '' - if (d > md || !obj || to !== 'object') return '' + obj - - if (Array.isArray(obj)) { - return obj.map(function (i, _, __) { - return custom(i, md, d + 1) - }).reduce(function (a, b) { return a + b }, '') - } - - var keys = Object.keys(obj) - return keys.map(function (k, _, __) { - return k + ':' + custom(obj[k], md, d + 1) - }).reduce(function (a, b) { return a + b }, '') -} - -function sparseFE2 (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - Object.keys(v).forEach(function (k, _, __) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') return - var to = typeof v[k] - if (to === 'function' || to === 'undefined') return - soFar += k + ':' - ch(v[k], depth + 1) - }) - soFar += '}' - } - ch(obj, 0) - return soFar -} - -function sparseFE (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - Object.keys(v).forEach(function (k, _, __) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') return - var to = typeof v[k] - if (to === 'function' || to === 'undefined') return - soFar += k - ch(v[k], depth + 1) - }) - } - ch(obj, 0) - return soFar -} - -function sparse (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k - ch(v[k], depth + 1) - } - } - ch(obj, 0) - return soFar -} - -function noCommas (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k + ':' - ch(v[k], depth + 1) - } - soFar += '}' - } - ch(obj, 0) - return soFar -} - - -function flatten (obj, maxDepth) { - var seen = [] - var soFar = '' - function ch (v, depth) { - if (depth > maxDepth) return - if (typeof v === 'function' || typeof v === 'undefined') return - if (typeof v !== 'object' || !v) { - soFar += v - return - } - if (seen.indexOf(v) !== -1 || depth === maxDepth) return - seen.push(v) - soFar += '{' - for (var k in v) { - // pseudo-private values. skip those. - if (k.charAt(0) === '_') continue - var to = typeof v[k] - if (to === 'function' || to === 'undefined') continue - soFar += k + ':' - ch(v[k], depth + 1) - soFar += ',' - } - soFar += '}' - } - ch(obj, 0) - return soFar -} - -exports.compare = -{ - // 'custom 2': function () { - // return custom(test, 2, 0) - // }, - // 'customWs 2': function () { - // return customWs(test, 2, 0) - // }, - 'JSON.stringify (guarded)': function () { - var seen = [] - return JSON.stringify(test, function (k, v) { - if (typeof v !== 'object' || !v) return v - if (seen.indexOf(v) !== -1) return undefined - seen.push(v) - return v - }) - }, - - 'flatten 10': function () { - return flatten(test, 10) - }, - - // 'flattenFE 10': function () { - // return flattenFE(test, 10) - // }, - - 'noCommas 10': function () { - return noCommas(test, 10) - }, - - 'sparse 10': function () { - return sparse(test, 10) - }, - - 'sparseFE 10': function () { - return sparseFE(test, 10) - }, - - 'sparseFE2 10': function () { - return sparseFE2(test, 10) - }, - - sigmund: function() { - return sigmund(test, 10) - }, - - - // 'util.inspect 1': function () { - // return util.inspect(test, false, 1, false) - // }, - // 'util.inspect undefined': function () { - // util.inspect(test) - // }, - // 'util.inspect 2': function () { - // util.inspect(test, false, 2, false) - // }, - // 'util.inspect 3': function () { - // util.inspect(test, false, 3, false) - // }, - // 'util.inspect 4': function () { - // util.inspect(test, false, 4, false) - // }, - // 'util.inspect Infinity': function () { - // util.inspect(test, false, Infinity, false) - // } -} - -/** results -**/ diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json deleted file mode 100644 index a1f755a7..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "sigmund", - "version": "1.0.0", - "description": "Quick and dirty signatures for Objects.", - "main": "sigmund.js", - "directories": { - "test": "test" - }, - "dependencies": {}, - "devDependencies": { - "tap": "~0.3.0" - }, - "scripts": { - "test": "tap test/*.js", - "bench": "node bench.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/sigmund" - }, - "keywords": [ - "object", - "signature", - "key", - "data", - "psychoanalysis" - ], - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "license": "BSD", - "readme": "# sigmund\n\nQuick and dirty signatures for Objects.\n\nThis is like a much faster `deepEquals` comparison, which returns a\nstring key suitable for caches and the like.\n\n## Usage\n\n```javascript\nfunction doSomething (someObj) {\n var key = sigmund(someObj, maxDepth) // max depth defaults to 10\n var cached = cache.get(key)\n if (cached) return cached)\n\n var result = expensiveCalculation(someObj)\n cache.set(key, result)\n return result\n}\n```\n\nThe resulting key will be as unique and reproducible as calling\n`JSON.stringify` or `util.inspect` on the object, but is much faster.\nIn order to achieve this speed, some differences are glossed over.\nFor example, the object `{0:'foo'}` will be treated identically to the\narray `['foo']`.\n\nAlso, just as there is no way to summon the soul from the scribblings\nof a cocain-addled psychoanalyst, there is no way to revive the object\nfrom the signature string that sigmund gives you. In fact, it's\nbarely even readable.\n\nAs with `sys.inspect` and `JSON.stringify`, larger objects will\nproduce larger signature strings.\n\nBecause sigmund is a bit less strict than the more thorough\nalternatives, the strings will be shorter, and also there is a\nslightly higher chance for collisions. For example, these objects\nhave the same signature:\n\n var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}\n var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}\n\nLike a good Freudian, sigmund is most effective when you already have\nsome understanding of what you're looking for. It can help you help\nyourself, but you must be willing to do some work as well.\n\nCycles are handled, and cyclical objects are silently omitted (though\nthe key is included in the signature output.)\n\nThe second argument is the maximum depth, which defaults to 10,\nbecause that is the maximum object traversal depth covered by most\ninsurance carriers.\n", - "_id": "sigmund@1.0.0", - "dist": { - "shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296", - "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz" - }, - "_npmVersion": "1.1.48", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_shasum": "66a2b3a749ae8b5fb89efd4fcc01dc94fbe02296", - "_from": "sigmund@~1.0.0", - "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz", - "bugs": { - "url": "https://github.com/isaacs/sigmund/issues" - }, - "homepage": "https://github.com/isaacs/sigmund" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js deleted file mode 100644 index 82c7ab8c..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = sigmund -function sigmund (subject, maxSessions) { - maxSessions = maxSessions || 10; - var notes = []; - var analysis = ''; - var RE = RegExp; - - function psychoAnalyze (subject, session) { - if (session > maxSessions) return; - - if (typeof subject === 'function' || - typeof subject === 'undefined') { - return; - } - - if (typeof subject !== 'object' || !subject || - (subject instanceof RE)) { - analysis += subject; - return; - } - - if (notes.indexOf(subject) !== -1 || session === maxSessions) return; - - notes.push(subject); - analysis += '{'; - Object.keys(subject).forEach(function (issue, _, __) { - // pseudo-private values. skip those. - if (issue.charAt(0) === '_') return; - var to = typeof subject[issue]; - if (to === 'function' || to === 'undefined') return; - analysis += issue; - psychoAnalyze(subject[issue], session + 1); - }); - } - psychoAnalyze(subject, 0); - return analysis; -} - -// vim: set softtabstop=4 shiftwidth=4: diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js deleted file mode 100644 index 50c53a13..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js +++ /dev/null @@ -1,24 +0,0 @@ -var test = require('tap').test -var sigmund = require('../sigmund.js') - - -// occasionally there are duplicates -// that's an acceptable edge-case. JSON.stringify and util.inspect -// have some collision potential as well, though less, and collision -// detection is expensive. -var hash = '{abc/def/g{0h1i2{jkl' -var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} -var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} - -var obj3 = JSON.parse(JSON.stringify(obj1)) -obj3.c = /def/ -obj3.g[2].cycle = obj3 -var cycleHash = '{abc/def/g{0h1i2{jklcycle' - -test('basic', function (t) { - t.equal(sigmund(obj1), hash) - t.equal(sigmund(obj2), hash) - t.equal(sigmund(obj3), cycleHash) - t.end() -}) - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json deleted file mode 100644 index 0fe147d6..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me" - }, - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "0.3.0", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "minimatch.js", - "scripts": { - "test": "tap test/*.js" - }, - "engines": { - "node": "*" - }, - "dependencies": { - "lru-cache": "2", - "sigmund": "~1.0.0" - }, - "devDependencies": { - "tap": "" - }, - "license": { - "type": "MIT", - "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/minimatch/issues" - }, - "homepage": "https://github.com/isaacs/minimatch", - "_id": "minimatch@0.3.0", - "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", - "_from": "minimatch@0.3", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", - "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js deleted file mode 100644 index ae7ac73c..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/basic.js +++ /dev/null @@ -1,399 +0,0 @@ -// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test -// -// TODO: Some of these tests do very bad things with backslashes, and will -// most likely fail badly on windows. They should probably be skipped. - -var tap = require("tap") - , globalBefore = Object.keys(global) - , mm = require("../") - , files = [ "a", "b", "c", "d", "abc" - , "abd", "abe", "bb", "bcd" - , "ca", "cb", "dd", "de" - , "bdir/", "bdir/cfile"] - , next = files.concat([ "a-b", "aXb" - , ".x", ".y" ]) - - -var patterns = - [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test" - , ["a*", ["a", "abc", "abd", "abe"]] - , ["X*", ["X*"], {nonull: true}] - - // allow null glob expansion - , ["X*", []] - - // isaacs: Slightly different than bash/sh/ksh - // \\* is not un-escaped to literal "*" in a failed match, - // but it does make it get treated as a literal star - , ["\\*", ["\\*"], {nonull: true}] - , ["\\**", ["\\**"], {nonull: true}] - , ["\\*\\*", ["\\*\\*"], {nonull: true}] - - , ["b*/", ["bdir/"]] - , ["c*", ["c", "ca", "cb"]] - , ["**", files] - - , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] - , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] - - , "legendary larry crashes bashes" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] - - , "character classes" - , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] - , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", - "bdir/", "ca", "cb", "dd", "de"]] - , ["a*[^c]", ["abd", "abe"]] - , function () { files.push("a-b", "aXb") } - , ["a[X-]b", ["a-b", "aXb"]] - , function () { files.push(".x", ".y") } - , ["[^a-c]*", ["d", "dd", "de"]] - , function () { files.push("a*b/", "a*b/ooo") } - , ["a\\*b/*", ["a*b/ooo"]] - , ["a\\*?/*", ["a*b/ooo"]] - , ["*\\\\!*", [], {null: true}, ["echo !7"]] - , ["*\\!*", ["echo !7"], null, ["echo !7"]] - , ["*.\\*", ["r.*"], null, ["r.*"]] - , ["a[b]c", ["abc"]] - , ["a[\\b]c", ["abc"]] - , ["a?c", ["abc"]] - , ["a\\*c", [], {null: true}, ["abc"]] - , ["", [""], { null: true }, [""]] - - , "http://www.opensource.apple.com/source/bash/bash-23/" + - "bash/tests/glob-test" - , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } - , ["*/man*/bash.*", ["man/man1/bash.1"]] - , ["man/man1/bash.1", ["man/man1/bash.1"]] - , ["a***c", ["abc"], null, ["abc"]] - , ["a*****?c", ["abc"], null, ["abc"]] - , ["?*****??", ["abc"], null, ["abc"]] - , ["*****??", ["abc"], null, ["abc"]] - , ["?*****?c", ["abc"], null, ["abc"]] - , ["?***?****c", ["abc"], null, ["abc"]] - , ["?***?****?", ["abc"], null, ["abc"]] - , ["?***?****", ["abc"], null, ["abc"]] - , ["*******c", ["abc"], null, ["abc"]] - , ["*******?", ["abc"], null, ["abc"]] - , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["[-abc]", ["-"], null, ["-"]] - , ["[abc-]", ["-"], null, ["-"]] - , ["\\", ["\\"], null, ["\\"]] - , ["[\\\\]", ["\\"], null, ["\\"]] - , ["[[]", ["["], null, ["["]] - , ["[", ["["], null, ["["]] - , ["[*", ["[abc"], null, ["[abc"]] - , "a right bracket shall lose its special meaning and\n" + - "represent itself in a bracket expression if it occurs\n" + - "first in the list. -- POSIX.2 2.8.3.2" - , ["[]]", ["]"], null, ["]"]] - , ["[]-]", ["]"], null, ["]"]] - , ["[a-\z]", ["p"], null, ["p"]] - , ["??**********?****?", [], { null: true }, ["abc"]] - , ["??**********?****c", [], { null: true }, ["abc"]] - , ["?************c****?****", [], { null: true }, ["abc"]] - , ["*c*?**", [], { null: true }, ["abc"]] - , ["a*****c*?**", [], { null: true }, ["abc"]] - , ["a********???*******", [], { null: true }, ["abc"]] - , ["[]", [], { null: true }, ["a"]] - , ["[abc", [], { null: true }, ["["]] - - , "nocase tests" - , ["XYZ", ["xYz"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["ab*", ["ABC"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - - // [ pattern, [matches], MM opts, files, TAP opts] - , "onestar/twostar" - , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] - , ["{/?,*}", ["/a", "bb"], {null: true} - , ["/a", "/b/b", "/a/b/c", "bb"]] - - , "dots should not match unless requested" - , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] - - // .. and . can only match patterns starting with ., - // even when options.dot is set. - , function () { - files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] - } - , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] - , ["a/*/b", ["a/c/b"], {dot:false}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] - - - // this also tests that changing the options needs - // to change the cache key, even if the pattern is - // the same! - , ["**", ["a/b","a/.d",".a/.d"], { dot: true } - , [ ".a/.d", "a/.d", "a/b"]] - - , "paren sets cannot contain slashes" - , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] - - // brace sets trump all else. - // - // invalid glob pattern. fails on bash4 and bsdglob. - // however, in this implementation, it's easier just - // to do the intuitive thing, and let brace-expansion - // actually come before parsing any extglob patterns, - // like the documentation seems to say. - // - // XXX: if anyone complains about this, either fix it - // or tell them to grow up and stop complaining. - // - // bash/bsdglob says this: - // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] - // but we do this instead: - , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] - - // test partial parsing in the presence of comment/negation chars - , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] - , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] - - // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. - , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] - , {} - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] - - - // crazy nested {,,} and *(||) tests. - , function () { - files = [ "a", "b", "c", "d" - , "ab", "ac", "ad" - , "bc", "cb" - , "bc,d", "c,db", "c,d" - , "d)", "(b|c", "*(b|c" - , "b|c", "b|cc", "cb|c" - , "x(a|b|c)", "x(a|c)" - , "(a|b|c)", "(a|c)"] - } - , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] - , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] - // a - // *(b|c) - // *(b|d) - , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] - , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] - - - // test various flag settings. - , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] - , { noext: true } ] - , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} - , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] - , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] - - - // begin channelling Boole and deMorgan... - , "negation tests" - , function () { - files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] - } - - // anything that is NOT a* matches. - , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] - - // anything that IS !a* matches. - , ["!a*", ["!ab", "!abc"], {nonegate: true}] - - // anything that IS a* matches - , ["!!a*", ["a!b"]] - - // anything that is NOT !a* matches - , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] - - // negation nestled within a pattern - , function () { - files = [ "foo.js" - , "foo.bar" - // can't match this one without negative lookbehind. - , "foo.js.js" - , "blar.js" - , "foo." - , "boo.js.boo" ] - } - , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] - - // https://github.com/isaacs/minimatch/issues/5 - , function () { - files = [ 'a/b/.x/c' - , 'a/b/.x/c/d' - , 'a/b/.x/c/d/e' - , 'a/b/.x' - , 'a/b/.x/' - , 'a/.x/b' - , '.x' - , '.x/' - , '.x/a' - , '.x/a/b' - , 'a/.x/b/.x/c' - , '.x/.x' ] - } - , ["**/.x/**", [ '.x/' - , '.x/a' - , '.x/a/b' - , 'a/.x/b' - , 'a/b/.x/' - , 'a/b/.x/c' - , 'a/b/.x/c/d' - , 'a/b/.x/c/d/e' ] ] - - ] - -var regexps = - [ '/^(?:(?=.)a[^/]*?)$/', - '/^(?:(?=.)X[^/]*?)$/', - '/^(?:(?=.)X[^/]*?)$/', - '/^(?:\\*)$/', - '/^(?:(?=.)\\*[^/]*?)$/', - '/^(?:\\*\\*)$/', - '/^(?:(?=.)b[^/]*?\\/)$/', - '/^(?:(?=.)c[^/]*?)$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', - '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/', - '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/', - '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/', - '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/', - '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/', - '/^(?:(?=.)a[^/]*?[^c])$/', - '/^(?:(?=.)a[X-]b)$/', - '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/', - '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/', - '/^(?:(?=.)a[b]c)$/', - '/^(?:(?=.)a[b]c)$/', - '/^(?:(?=.)a[^/]c)$/', - '/^(?:a\\*c)$/', - 'false', - '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/', - '/^(?:man\\/man1\\/bash\\.1)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[-abc])$/', - '/^(?:(?!\\.)(?=.)[abc-])$/', - '/^(?:\\\\)$/', - '/^(?:(?!\\.)(?=.)[\\\\])$/', - '/^(?:(?!\\.)(?=.)[\\[])$/', - '/^(?:\\[)$/', - '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[\\]])$/', - '/^(?:(?!\\.)(?=.)[\\]-])$/', - '/^(?:(?!\\.)(?=.)[a-z])$/', - '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', - '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', - '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', - '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', - '/^(?:\\[\\])$/', - '/^(?:\\[abc)$/', - '/^(?:(?=.)XYZ)$/i', - '/^(?:(?=.)ab[^/]*?)$/i', - '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i', - '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/', - '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', - '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/', - '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', - '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/', - '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', - '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/', - '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/', - '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/', - '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/', - '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/', - '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/', - '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/', - '/^(?:(?=.)a[^/]b)$/', - '/^(?:(?=.)#[^/]*?)$/', - '/^(?!^(?:(?=.)a[^/]*?)$).*$/', - '/^(?:(?=.)\\!a[^/]*?)$/', - '/^(?:(?=.)a[^/]*?)$/', - '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/', - '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/', - '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ] -var re = 0; - -tap.test("basic tests", function (t) { - var start = Date.now() - - // [ pattern, [matches], MM opts, files, TAP opts] - patterns.forEach(function (c) { - if (typeof c === "function") return c() - if (typeof c === "string") return t.comment(c) - - var pattern = c[0] - , expect = c[1].sort(alpha) - , options = c[2] || {} - , f = c[3] || files - , tapOpts = c[4] || {} - - // options.debug = true - var m = new mm.Minimatch(pattern, options) - var r = m.makeRe() - var expectRe = regexps[re++] - tapOpts.re = String(r) || JSON.stringify(r) - tapOpts.files = JSON.stringify(f) - tapOpts.pattern = pattern - tapOpts.set = m.set - tapOpts.negated = m.negate - - var actual = mm.match(f, pattern, options) - actual.sort(alpha) - - t.equivalent( actual, expect - , JSON.stringify(pattern) + " " + JSON.stringify(expect) - , tapOpts ) - - t.equal(tapOpts.re, expectRe, tapOpts) - }) - - t.comment("time=" + (Date.now() - start) + "ms") - t.end() -}) - -tap.test("global leak test", function (t) { - var globalAfter = Object.keys(global) - t.equivalent(globalAfter, globalBefore, "no new globals, please") - t.end() -}) - -function alpha (a, b) { - return a > b ? 1 : -1 -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js deleted file mode 100644 index 7ee278a2..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/brace-expand.js +++ /dev/null @@ -1,33 +0,0 @@ -var tap = require("tap") - , minimatch = require("../") - -tap.test("brace expansion", function (t) { - // [ pattern, [expanded] ] - ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}" - , [ "abxy" - , "abxz" - , "acdxy" - , "acdxz" - , "acexy" - , "acexz" - , "afhxy" - , "afhxz" - , "aghxy" - , "aghxz" ] ] - , [ "a{1..5}b" - , [ "a1b" - , "a2b" - , "a3b" - , "a4b" - , "a5b" ] ] - , [ "a{b}c", ["a{b}c"] ] - ].forEach(function (tc) { - var p = tc[0] - , expect = tc[1] - t.equivalent(minimatch.braceExpand(p), expect, p) - }) - console.error("ending") - t.end() -}) - - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js deleted file mode 100644 index 0fec4b0f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/caching.js +++ /dev/null @@ -1,14 +0,0 @@ -var Minimatch = require("../minimatch.js").Minimatch -var tap = require("tap") -tap.test("cache test", function (t) { - var mm1 = new Minimatch("a?b") - var mm2 = new Minimatch("a?b") - t.equal(mm1, mm2, "should get the same object") - // the lru should drop it after 100 entries - for (var i = 0; i < 100; i ++) { - new Minimatch("a"+i) - } - mm2 = new Minimatch("a?b") - t.notEqual(mm1, mm2, "cache should have dropped") - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js deleted file mode 100644 index 75e05712..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/defaults.js +++ /dev/null @@ -1,274 +0,0 @@ -// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test -// -// TODO: Some of these tests do very bad things with backslashes, and will -// most likely fail badly on windows. They should probably be skipped. - -var tap = require("tap") - , globalBefore = Object.keys(global) - , mm = require("../") - , files = [ "a", "b", "c", "d", "abc" - , "abd", "abe", "bb", "bcd" - , "ca", "cb", "dd", "de" - , "bdir/", "bdir/cfile"] - , next = files.concat([ "a-b", "aXb" - , ".x", ".y" ]) - -tap.test("basic tests", function (t) { - var start = Date.now() - - // [ pattern, [matches], MM opts, files, TAP opts] - ; [ "http://www.bashcookbook.com/bashinfo" + - "/source/bash-1.14.7/tests/glob-test" - , ["a*", ["a", "abc", "abd", "abe"]] - , ["X*", ["X*"], {nonull: true}] - - // allow null glob expansion - , ["X*", []] - - // isaacs: Slightly different than bash/sh/ksh - // \\* is not un-escaped to literal "*" in a failed match, - // but it does make it get treated as a literal star - , ["\\*", ["\\*"], {nonull: true}] - , ["\\**", ["\\**"], {nonull: true}] - , ["\\*\\*", ["\\*\\*"], {nonull: true}] - - , ["b*/", ["bdir/"]] - , ["c*", ["c", "ca", "cb"]] - , ["**", files] - - , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] - , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] - - , "legendary larry crashes bashes" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" - , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] - - , "character classes" - , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] - , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", - "bdir/", "ca", "cb", "dd", "de"]] - , ["a*[^c]", ["abd", "abe"]] - , function () { files.push("a-b", "aXb") } - , ["a[X-]b", ["a-b", "aXb"]] - , function () { files.push(".x", ".y") } - , ["[^a-c]*", ["d", "dd", "de"]] - , function () { files.push("a*b/", "a*b/ooo") } - , ["a\\*b/*", ["a*b/ooo"]] - , ["a\\*?/*", ["a*b/ooo"]] - , ["*\\\\!*", [], {null: true}, ["echo !7"]] - , ["*\\!*", ["echo !7"], null, ["echo !7"]] - , ["*.\\*", ["r.*"], null, ["r.*"]] - , ["a[b]c", ["abc"]] - , ["a[\\b]c", ["abc"]] - , ["a?c", ["abc"]] - , ["a\\*c", [], {null: true}, ["abc"]] - , ["", [""], { null: true }, [""]] - - , "http://www.opensource.apple.com/source/bash/bash-23/" + - "bash/tests/glob-test" - , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } - , ["*/man*/bash.*", ["man/man1/bash.1"]] - , ["man/man1/bash.1", ["man/man1/bash.1"]] - , ["a***c", ["abc"], null, ["abc"]] - , ["a*****?c", ["abc"], null, ["abc"]] - , ["?*****??", ["abc"], null, ["abc"]] - , ["*****??", ["abc"], null, ["abc"]] - , ["?*****?c", ["abc"], null, ["abc"]] - , ["?***?****c", ["abc"], null, ["abc"]] - , ["?***?****?", ["abc"], null, ["abc"]] - , ["?***?****", ["abc"], null, ["abc"]] - , ["*******c", ["abc"], null, ["abc"]] - , ["*******?", ["abc"], null, ["abc"]] - , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] - , ["[-abc]", ["-"], null, ["-"]] - , ["[abc-]", ["-"], null, ["-"]] - , ["\\", ["\\"], null, ["\\"]] - , ["[\\\\]", ["\\"], null, ["\\"]] - , ["[[]", ["["], null, ["["]] - , ["[", ["["], null, ["["]] - , ["[*", ["[abc"], null, ["[abc"]] - , "a right bracket shall lose its special meaning and\n" + - "represent itself in a bracket expression if it occurs\n" + - "first in the list. -- POSIX.2 2.8.3.2" - , ["[]]", ["]"], null, ["]"]] - , ["[]-]", ["]"], null, ["]"]] - , ["[a-\z]", ["p"], null, ["p"]] - , ["??**********?****?", [], { null: true }, ["abc"]] - , ["??**********?****c", [], { null: true }, ["abc"]] - , ["?************c****?****", [], { null: true }, ["abc"]] - , ["*c*?**", [], { null: true }, ["abc"]] - , ["a*****c*?**", [], { null: true }, ["abc"]] - , ["a********???*******", [], { null: true }, ["abc"]] - , ["[]", [], { null: true }, ["a"]] - , ["[abc", [], { null: true }, ["["]] - - , "nocase tests" - , ["XYZ", ["xYz"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["ab*", ["ABC"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } - , ["xYz", "ABC", "IjK"]] - - // [ pattern, [matches], MM opts, files, TAP opts] - , "onestar/twostar" - , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] - , ["{/?,*}", ["/a", "bb"], {null: true} - , ["/a", "/b/b", "/a/b/c", "bb"]] - - , "dots should not match unless requested" - , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] - - // .. and . can only match patterns starting with ., - // even when options.dot is set. - , function () { - files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] - } - , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] - , ["a/*/b", ["a/c/b"], {dot:false}] - , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] - - - // this also tests that changing the options needs - // to change the cache key, even if the pattern is - // the same! - , ["**", ["a/b","a/.d",".a/.d"], { dot: true } - , [ ".a/.d", "a/.d", "a/b"]] - - , "paren sets cannot contain slashes" - , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] - - // brace sets trump all else. - // - // invalid glob pattern. fails on bash4 and bsdglob. - // however, in this implementation, it's easier just - // to do the intuitive thing, and let brace-expansion - // actually come before parsing any extglob patterns, - // like the documentation seems to say. - // - // XXX: if anyone complains about this, either fix it - // or tell them to grow up and stop complaining. - // - // bash/bsdglob says this: - // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] - // but we do this instead: - , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] - - // test partial parsing in the presence of comment/negation chars - , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] - , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] - - // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. - , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] - , {} - , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] - - - // crazy nested {,,} and *(||) tests. - , function () { - files = [ "a", "b", "c", "d" - , "ab", "ac", "ad" - , "bc", "cb" - , "bc,d", "c,db", "c,d" - , "d)", "(b|c", "*(b|c" - , "b|c", "b|cc", "cb|c" - , "x(a|b|c)", "x(a|c)" - , "(a|b|c)", "(a|c)"] - } - , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] - , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] - // a - // *(b|c) - // *(b|d) - , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] - , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] - - - // test various flag settings. - , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] - , { noext: true } ] - , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} - , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] - , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] - - - // begin channelling Boole and deMorgan... - , "negation tests" - , function () { - files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] - } - - // anything that is NOT a* matches. - , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] - - // anything that IS !a* matches. - , ["!a*", ["!ab", "!abc"], {nonegate: true}] - - // anything that IS a* matches - , ["!!a*", ["a!b"]] - - // anything that is NOT !a* matches - , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] - - // negation nestled within a pattern - , function () { - files = [ "foo.js" - , "foo.bar" - // can't match this one without negative lookbehind. - , "foo.js.js" - , "blar.js" - , "foo." - , "boo.js.boo" ] - } - , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] - - ].forEach(function (c) { - if (typeof c === "function") return c() - if (typeof c === "string") return t.comment(c) - - var pattern = c[0] - , expect = c[1].sort(alpha) - , options = c[2] - , f = c[3] || files - , tapOpts = c[4] || {} - - // options.debug = true - var Class = mm.defaults(options).Minimatch - var m = new Class(pattern, {}) - var r = m.makeRe() - tapOpts.re = String(r) || JSON.stringify(r) - tapOpts.files = JSON.stringify(f) - tapOpts.pattern = pattern - tapOpts.set = m.set - tapOpts.negated = m.negate - - var actual = mm.match(f, pattern, options) - actual.sort(alpha) - - t.equivalent( actual, expect - , JSON.stringify(pattern) + " " + JSON.stringify(expect) - , tapOpts ) - }) - - t.comment("time=" + (Date.now() - start) + "ms") - t.end() -}) - -tap.test("global leak test", function (t) { - var globalAfter = Object.keys(global) - t.equivalent(globalAfter, globalBefore, "no new globals, please") - t.end() -}) - -function alpha (a, b) { - return a > b ? 1 : -1 -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js deleted file mode 100644 index 6676e262..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js +++ /dev/null @@ -1,8 +0,0 @@ -var test = require('tap').test -var minimatch = require('../') - -test('extglob ending with statechar', function(t) { - t.notOk(minimatch('ax', 'a?(b*)')) - t.ok(minimatch('ax', '?(a*|b)')) - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/package.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/package.json deleted file mode 100644 index e7ec15f3..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me/" - }, - "name": "glob", - "description": "a little globber", - "version": "3.2.11", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "main": "glob.js", - "engines": { - "node": "*" - }, - "dependencies": { - "inherits": "2", - "minimatch": "0.3" - }, - "devDependencies": { - "tap": "~0.4.0", - "mkdirp": "0", - "rimraf": "1" - }, - "scripts": { - "test": "tap test/*.js", - "test-regen": "TEST_REGEN=1 node test/00-setup.js" - }, - "license": "BSD", - "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", - "bugs": { - "url": "https://github.com/isaacs/node-glob/issues" - }, - "homepage": "https://github.com/isaacs/node-glob", - "_id": "glob@3.2.11", - "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", - "_from": "glob@~3.2.9", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", - "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/00-setup.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/00-setup.js deleted file mode 100644 index 245afafd..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/00-setup.js +++ /dev/null @@ -1,176 +0,0 @@ -// just a little pre-run script to set up the fixtures. -// zz-finish cleans it up - -var mkdirp = require("mkdirp") -var path = require("path") -var i = 0 -var tap = require("tap") -var fs = require("fs") -var rimraf = require("rimraf") - -var files = -[ "a/.abcdef/x/y/z/a" -, "a/abcdef/g/h" -, "a/abcfed/g/h" -, "a/b/c/d" -, "a/bc/e/f" -, "a/c/d/c/b" -, "a/cb/e/f" -] - -var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") -var symlinkFrom = "../.." - -files = files.map(function (f) { - return path.resolve(__dirname, f) -}) - -tap.test("remove fixtures", function (t) { - rimraf(path.resolve(__dirname, "a"), function (er) { - t.ifError(er, "remove fixtures") - t.end() - }) -}) - -files.forEach(function (f) { - tap.test(f, function (t) { - var d = path.dirname(f) - mkdirp(d, 0755, function (er) { - if (er) { - t.fail(er) - return t.bailout() - } - fs.writeFile(f, "i like tests", function (er) { - t.ifError(er, "make file") - t.end() - }) - }) - }) -}) - -if (process.platform !== "win32") { - tap.test("symlinky", function (t) { - var d = path.dirname(symlinkTo) - console.error("mkdirp", d) - mkdirp(d, 0755, function (er) { - t.ifError(er) - fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) { - t.ifError(er, "make symlink") - t.end() - }) - }) - }) -} - -;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { - w = "/tmp/glob-test/" + w - tap.test("create " + w, function (t) { - mkdirp(w, function (er) { - if (er) - throw er - t.pass(w) - t.end() - }) - }) -}) - - -// generate the bash pattern test-fixtures if possible -if (process.platform === "win32" || !process.env.TEST_REGEN) { - console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") - return -} - -var spawn = require("child_process").spawn; -var globs = - // put more patterns here. - // anything that would be directly in / should be in /tmp/glob-test - ["test/a/*/+(c|g)/./d" - ,"test/a/**/[cg]/../[cg]" - ,"test/a/{b,c,d,e,f}/**/g" - ,"test/a/b/**" - ,"test/**/g" - ,"test/a/abc{fed,def}/g/h" - ,"test/a/abc{fed/g,def}/**/" - ,"test/a/abc{fed/g,def}/**///**/" - ,"test/**/a/**/" - ,"test/+(a|b|c)/a{/,bc*}/**" - ,"test/*/*/*/f" - ,"test/**/f" - ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" - ,"{./*/*,/tmp/glob-test/*}" - ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! - ,"test/a/!(symlink)/**" - ] -var bashOutput = {} -var fs = require("fs") - -globs.forEach(function (pattern) { - tap.test("generate fixture " + pattern, function (t) { - var cmd = "shopt -s globstar && " + - "shopt -s extglob && " + - "shopt -s nullglob && " + - // "shopt >&2; " + - "eval \'for i in " + pattern + "; do echo $i; done\'" - var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) }) - var out = [] - cp.stdout.on("data", function (c) { - out.push(c) - }) - cp.stderr.pipe(process.stderr) - cp.on("close", function (code) { - out = flatten(out) - if (!out) - out = [] - else - out = cleanResults(out.split(/\r*\n/)) - - bashOutput[pattern] = out - t.notOk(code, "bash test should finish nicely") - t.end() - }) - }) -}) - -tap.test("save fixtures", function (t) { - var fname = path.resolve(__dirname, "bash-results.json") - var data = JSON.stringify(bashOutput, null, 2) + "\n" - fs.writeFile(fname, data, function (er) { - t.ifError(er) - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -function flatten (chunks) { - var s = 0 - chunks.forEach(function (c) { s += c.length }) - var out = new Buffer(s) - s = 0 - chunks.forEach(function (c) { - c.copy(out, s) - s += c.length - }) - - return out.toString().trim() -} - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js deleted file mode 100644 index 239ed1a9..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-comparison.js +++ /dev/null @@ -1,63 +0,0 @@ -// basic test -// show that it does the same thing by default as the shell. -var tap = require("tap") -, child_process = require("child_process") -, bashResults = require("./bash-results.json") -, globs = Object.keys(bashResults) -, glob = require("../") -, path = require("path") - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -process.chdir(path.resolve(__dirname, "..")) - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -globs.forEach(function (pattern) { - var expect = bashResults[pattern] - // anything regarding the symlink thing will fail on windows, so just skip it - if (process.platform === "win32" && - expect.some(function (m) { - return /\/symlink\//.test(m) - })) - return - - tap.test(pattern, function (t) { - glob(pattern, function (er, matches) { - if (er) - throw er - - // sort and unmark, just to match the shell results - matches = cleanResults(matches) - - t.deepEqual(matches, expect, pattern) - t.end() - }) - }) - - tap.test(pattern + " sync", function (t) { - var matches = cleanResults(glob.sync(pattern)) - - t.deepEqual(matches, expect, "should match shell") - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') - }) -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-results.json b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-results.json deleted file mode 100644 index 8051c723..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/bash-results.json +++ /dev/null @@ -1,351 +0,0 @@ -{ - "test/a/*/+(c|g)/./d": [ - "test/a/b/c/./d" - ], - "test/a/**/[cg]/../[cg]": [ - "test/a/abcdef/g/../g", - "test/a/abcfed/g/../g", - "test/a/b/c/../c", - "test/a/c/../c", - "test/a/c/d/c/../c", - "test/a/symlink/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c" - ], - "test/a/{b,c,d,e,f}/**/g": [], - "test/a/b/**": [ - "test/a/b", - "test/a/b/c", - "test/a/b/c/d" - ], - "test/**/g": [ - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/a/abc{fed,def}/g/h": [ - "test/a/abcdef/g/h", - "test/a/abcfed/g/h" - ], - "test/a/abc{fed/g,def}/**/": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/a/abc{fed/g,def}/**///**/": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed/g" - ], - "test/**/a/**/": [ - "test/a", - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/b", - "test/a/b/c", - "test/a/bc", - "test/a/bc/e", - "test/a/c", - "test/a/c/d", - "test/a/c/d/c", - "test/a/cb", - "test/a/cb/e", - "test/a/symlink", - "test/a/symlink/a", - "test/a/symlink/a/b", - "test/a/symlink/a/b/c", - "test/a/symlink/a/b/c/a", - "test/a/symlink/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b" - ], - "test/+(a|b|c)/a{/,bc*}/**": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcdef/g/h", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/abcfed/g/h" - ], - "test/*/*/*/f": [ - "test/a/bc/e/f", - "test/a/cb/e/f" - ], - "test/**/f": [ - "test/a/bc/e/f", - "test/a/cb/e/f" - ], - "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" - ], - "{./*/*,/tmp/glob-test/*}": [ - "./examples/g.js", - "./examples/usr-local.js", - "./node_modules/inherits", - "./node_modules/minimatch", - "./node_modules/mkdirp", - "./node_modules/rimraf", - "./node_modules/tap", - "./test/00-setup.js", - "./test/a", - "./test/bash-comparison.js", - "./test/bash-results.json", - "./test/cwd-test.js", - "./test/globstar-match.js", - "./test/mark.js", - "./test/new-glob-optional-options.js", - "./test/nocase-nomagic.js", - "./test/pause-resume.js", - "./test/readme-issue.js", - "./test/root-nomount.js", - "./test/root.js", - "./test/stat.js", - "./test/zz-cleanup.js", - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq" - ], - "{/tmp/glob-test/*,*}": [ - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq", - "examples", - "glob.js", - "LICENSE", - "node_modules", - "package.json", - "README.md", - "test" - ], - "test/a/!(symlink)/**": [ - "test/a/abcdef", - "test/a/abcdef/g", - "test/a/abcdef/g/h", - "test/a/abcfed", - "test/a/abcfed/g", - "test/a/abcfed/g/h", - "test/a/b", - "test/a/b/c", - "test/a/b/c/d", - "test/a/bc", - "test/a/bc/e", - "test/a/bc/e/f", - "test/a/c", - "test/a/c/d", - "test/a/c/d/c", - "test/a/c/d/c/b", - "test/a/cb", - "test/a/cb/e", - "test/a/cb/e/f" - ] -} diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/cwd-test.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/cwd-test.js deleted file mode 100644 index 352c27ef..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/cwd-test.js +++ /dev/null @@ -1,55 +0,0 @@ -var tap = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -tap.test("changing cwd and searching for **/d", function (t) { - var glob = require('../') - var path = require('path') - t.test('.', function (t) { - glob('**/d', function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) - t.end() - }) - }) - - t.test('a', function (t) { - glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'b/c/d', 'c/d' ]) - t.end() - }) - }) - - t.test('a/b', function (t) { - glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) - t.end() - }) - }) - - t.test('a/b/', function (t) { - glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) - t.end() - }) - }) - - t.test('.', function (t) { - glob('**/d', {cwd: process.cwd()}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) - t.end() - }) - }) - - t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() - }) - - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/globstar-match.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/globstar-match.js deleted file mode 100644 index 9b234fa2..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/globstar-match.js +++ /dev/null @@ -1,19 +0,0 @@ -var Glob = require("../glob.js").Glob -var test = require('tap').test - -test('globstar should not have dupe matches', function(t) { - var pattern = 'a/**/[gh]' - var g = new Glob(pattern, { cwd: __dirname }) - var matches = [] - g.on('match', function(m) { - console.error('match %j', m) - matches.push(m) - }) - g.on('end', function(set) { - console.error('set', set) - matches = matches.sort() - set = set.sort() - t.same(matches, set, 'should have same set of matches') - t.end() - }) -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/mark.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/mark.js deleted file mode 100644 index bf411c0e..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/mark.js +++ /dev/null @@ -1,118 +0,0 @@ -var test = require("tap").test -var glob = require('../') -process.chdir(__dirname) - -// expose timing issues -var lag = 5 -glob.Glob.prototype._stat = function(o) { return function(f, cb) { - var args = arguments - setTimeout(function() { - o.call(this, f, cb) - }.bind(this), lag += 5) -}}(glob.Glob.prototype._stat) - - -test("mark, with **", function (t) { - glob("a/*b*/**", {mark: true}, function (er, results) { - if (er) - throw er - var expect = - [ 'a/abcdef/', - 'a/abcdef/g/', - 'a/abcdef/g/h', - 'a/abcfed/', - 'a/abcfed/g/', - 'a/abcfed/g/h', - 'a/b/', - 'a/b/c/', - 'a/b/c/d', - 'a/bc/', - 'a/bc/e/', - 'a/bc/e/f', - 'a/cb/', - 'a/cb/e/', - 'a/cb/e/f' ] - - t.same(results, expect) - t.end() - }) -}) - -test("mark, no / on pattern", function (t) { - glob("a/*", {mark: true}, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - - if (process.platform !== "win32") - expect.push('a/symlink/') - - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) - -test("mark=false, no / on pattern", function (t) { - glob("a/*", function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef', - 'a/abcfed', - 'a/b', - 'a/bc', - 'a/c', - 'a/cb' ] - - if (process.platform !== "win32") - expect.push('a/symlink') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /[^\/]$/) - }) -}) - -test("mark=true, / on pattern", function (t) { - glob("a/*/", {mark: true}, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) - -test("mark=false, / on pattern", function (t) { - glob("a/*/", function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') - t.same(results, expect) - t.end() - }).on('match', function(m) { - t.similar(m, /\/$/) - }) -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js deleted file mode 100644 index 3e7dc5ac..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/new-glob-optional-options.js +++ /dev/null @@ -1,10 +0,0 @@ -var Glob = require('../glob.js').Glob; -var test = require('tap').test; - -test('new glob, with cb, and no options', function (t) { - new Glob(__filename, function(er, results) { - if (er) throw er; - t.same(results, [__filename]); - t.end(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js deleted file mode 100644 index 2503f231..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/nocase-nomagic.js +++ /dev/null @@ -1,113 +0,0 @@ -var fs = require('fs'); -var test = require('tap').test; -var glob = require('../'); - -test('mock fs', function(t) { - var stat = fs.stat - var statSync = fs.statSync - var readdir = fs.readdir - var readdirSync = fs.readdirSync - - function fakeStat(path) { - var ret - switch (path.toLowerCase()) { - case '/tmp': case '/tmp/': - ret = { isDirectory: function() { return true } } - break - case '/tmp/a': - ret = { isDirectory: function() { return false } } - break - } - return ret - } - - fs.stat = function(path, cb) { - var f = fakeStat(path); - if (f) { - process.nextTick(function() { - cb(null, f) - }) - } else { - stat.call(fs, path, cb) - } - } - - fs.statSync = function(path) { - return fakeStat(path) || statSync.call(fs, path) - } - - function fakeReaddir(path) { - var ret - switch (path.toLowerCase()) { - case '/tmp': case '/tmp/': - ret = [ 'a', 'A' ] - break - case '/': - ret = ['tmp', 'tMp', 'tMP', 'TMP'] - } - return ret - } - - fs.readdir = function(path, cb) { - var f = fakeReaddir(path) - if (f) - process.nextTick(function() { - cb(null, f) - }) - else - readdir.call(fs, path, cb) - } - - fs.readdirSync = function(path) { - return fakeReaddir(path) || readdirSync.call(fs, path) - } - - t.pass('mocked') - t.end() -}) - -test('nocase, nomagic', function(t) { - var n = 2 - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - glob('/tmp/a', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - if (--n === 0) t.end() - }) - glob('/tmp/A', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - if (--n === 0) t.end() - }) -}) - -test('nocase, with some magic', function(t) { - t.plan(2) - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - }) - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er - t.same(res.sort(), want) - }) -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/pause-resume.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/pause-resume.js deleted file mode 100644 index e1ffbab1..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/pause-resume.js +++ /dev/null @@ -1,73 +0,0 @@ -// show that no match events happen while paused. -var tap = require("tap") -, child_process = require("child_process") -// just some gnarly pattern with lots of matches -, pattern = "test/a/!(symlink)/**" -, bashResults = require("./bash-results.json") -, patterns = Object.keys(bashResults) -, glob = require("../") -, Glob = glob.Glob -, path = require("path") - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -process.chdir(path.resolve(__dirname, "..")) - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -var globResults = [] -tap.test("use a Glob object, and pause/resume it", function (t) { - var g = new Glob(pattern) - , paused = false - , res = [] - , expect = bashResults[pattern] - - g.on("pause", function () { - console.error("pause") - }) - - g.on("resume", function () { - console.error("resume") - }) - - g.on("match", function (m) { - t.notOk(g.paused, "must not be paused") - globResults.push(m) - g.pause() - t.ok(g.paused, "must be paused") - setTimeout(g.resume.bind(g), 10) - }) - - g.on("end", function (matches) { - t.pass("reached glob end") - globResults = cleanResults(globResults) - matches = cleanResults(matches) - t.deepEqual(matches, globResults, - "end event matches should be the same as match events") - - t.deepEqual(matches, expect, - "glob matches should be the same as bash results") - - t.end() - }) -}) - diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/readme-issue.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/readme-issue.js deleted file mode 100644 index 0b4e0be2..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/readme-issue.js +++ /dev/null @@ -1,36 +0,0 @@ -var test = require("tap").test -var glob = require("../") - -var mkdirp = require("mkdirp") -var fs = require("fs") -var rimraf = require("rimraf") -var dir = __dirname + "/package" - -test("setup", function (t) { - mkdirp.sync(dir) - fs.writeFileSync(dir + "/package.json", "{}", "ascii") - fs.writeFileSync(dir + "/README", "x", "ascii") - t.pass("setup done") - t.end() -}) - -test("glob", function (t) { - var opt = { - cwd: dir, - nocase: true, - mark: true - } - - glob("README?(.*)", opt, function (er, files) { - if (er) - throw er - t.same(files, ["README"]) - t.end() - }) -}) - -test("cleanup", function (t) { - rimraf.sync(dir) - t.pass("clean") - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root-nomount.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root-nomount.js deleted file mode 100644 index 3ac5979b..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root-nomount.js +++ /dev/null @@ -1,39 +0,0 @@ -var tap = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -tap.test("changing root and searching for /b*/**", function (t) { - var glob = require('../') - var path = require('path') - t.test('.', function (t) { - glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, []) - t.end() - }) - }) - - t.test('a', function (t) { - glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - t.end() - }) - }) - - t.test('root=a, cwd=a/b', function (t) { - glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - t.end() - }) - }) - - t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() - }) - - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root.js deleted file mode 100644 index 95c23f99..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/root.js +++ /dev/null @@ -1,46 +0,0 @@ -var t = require("tap") - -var origCwd = process.cwd() -process.chdir(__dirname) - -var glob = require('../') -var path = require('path') - -t.test('.', function (t) { - glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { - t.ifError(er) - t.like(matches, []) - t.end() - }) -}) - - -t.test('a', function (t) { - console.error("root=" + path.resolve('a')) - glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { - t.ifError(er) - var wanted = [ - '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' - ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - }) - - t.like(matches, wanted) - t.end() - }) -}) - -t.test('root=a, cwd=a/b', function (t) { - glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - })) - t.end() - }) -}) - -t.test('cd -', function (t) { - process.chdir(origCwd) - t.end() -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/stat.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/stat.js deleted file mode 100644 index 62917114..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/stat.js +++ /dev/null @@ -1,32 +0,0 @@ -var glob = require('../') -var test = require('tap').test -var path = require('path') - -test('stat all the things', function(t) { - var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname }) - var matches = [] - g.on('match', function(m) { - matches.push(m) - }) - var stats = [] - g.on('stat', function(m) { - stats.push(m) - }) - g.on('end', function(eof) { - stats = stats.sort() - matches = matches.sort() - eof = eof.sort() - t.same(stats, matches) - t.same(eof, matches) - var cache = Object.keys(this.statCache) - t.same(cache.map(function (f) { - return path.relative(__dirname, f) - }).sort(), matches) - - cache.forEach(function(c) { - t.equal(typeof this.statCache[c], 'object') - }, this) - - t.end() - }) -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js deleted file mode 100644 index e085f0fa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/glob/test/zz-cleanup.js +++ /dev/null @@ -1,11 +0,0 @@ -// remove the fixtures -var tap = require("tap") -, rimraf = require("rimraf") -, path = require("path") - -tap.test("cleanup fixtures", function (t) { - rimraf(path.resolve(__dirname, "a"), function (er) { - t.ifError(er, "removed") - t.end() - }) -}) diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/LICENSE.txt b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/LICENSE.txt deleted file mode 100644 index 49869bba..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright 2012-2013 The Dojo Foundation -Based on Underscore.js 1.5.2, copyright 2009-2013 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. \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/README.md b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/README.md deleted file mode 100644 index 6f9598e8..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Lo-Dash v2.4.1 -A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features). - -## Download - -Check out our [wiki]([https://github.com/lodash/lodash/wiki/build-differences]) for details over the differences between builds. - -* Modern builds perfect for newer browsers/environments:
                  -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.min.js) - -* Compatibility builds for older environment support too:
                  -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.compat.min.js) - -* Underscore builds to use as a drop-in replacement:
                  -[Development](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js) & -[Production](https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.min.js) - -CDN copies are available on [cdnjs](http://cdnjs.com/libraries/lodash.js/) & [jsDelivr](http://www.jsdelivr.com/#!lodash). For smaller file sizes, create [custom builds](http://lodash.com/custom-builds) with only the features needed. - -Love modules? We’ve got you covered with [lodash-amd](https://npmjs.org/package/lodash-amd), [lodash-es6](https://github.com/lodash/lodash-es6), [lodash-node](https://npmjs.org/package/lodash-node), & [npm packages](https://npmjs.org/browse/keyword/lodash-modularized) per method. - -## Dive in - -There’s plenty of **[documentation](http://lodash.com/docs)**, [unit tests](http://lodash.com/tests), & [benchmarks](http://lodash.com/benchmarks).
                  -Check out
                  DevDocs as a fast, organized, & searchable interface for our documentation. - -The full changelog for this release is available on our [wiki](https://github.com/lodash/lodash/wiki/Changelog).
                  -A list of upcoming features is available on our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). - -## Features *not* in Underscore - - * AMD loader support ([curl](https://github.com/cujojs/curl), [dojo](http://dojotoolkit.org/), [requirejs](http://requirejs.org/), etc.) - * [_(…)](http://lodash.com/docs#_) supports intuitive chaining - * [_.at](http://lodash.com/docs#at) for cherry-picking collection values - * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazyâ€*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods - * [_.clone](http://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects - * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays & objects - * [_.constant](http://lodash.com/docs#constant) & [_.property](http://lodash.com/docs#property) function generators for composing functions - * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` - * [_.create](http://lodash.com/docs#create) for easier object inheritance - * [_.createCallback](http://lodash.com/docs#createCallback) for extending callbacks in methods & mixins - * [_.curry](http://lodash.com/docs#curry) for creating [curried](http://hughfdjackson.com/javascript/2013/07/06/why-curry-helps/) functions - * [_.debounce](http://lodash.com/docs#debounce) & [_.throttle](http://lodash.com/docs#throttle) accept additional `options` for more control - * [_.findIndex](http://lodash.com/docs#findIndex) & [_.findKey](http://lodash.com/docs#findKey) for finding indexes & keys - * [_.forEach](http://lodash.com/docs#forEach) is chainable & supports exiting early - * [_.forIn](http://lodash.com/docs#forIn) for iterating own & inherited properties - * [_.forOwn](http://lodash.com/docs#forOwn) for iterating own properties - * [_.isPlainObject](http://lodash.com/docs#isPlainObject) for checking if values are created by `Object` - * [_.mapValues](http://lodash.com/docs#mapValues) for [mapping](http://lodash.com/docs#map) values to an object - * [_.memoize](http://lodash.com/docs#memoize) exposes the `cache` of memoized functions - * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend) - * [_.noop](http://lodash.com/docs#noop) for function placeholders - * [_.now](http://lodash.com/docs#now) as a cross-browser `Date.now` alternative - * [_.parseInt](http://lodash.com/docs#parseInt) for consistent behavior - * [_.pull](http://lodash.com/docs#pull) & [_.remove](http://lodash.com/docs#remove) for mutating arrays - * [_.random](http://lodash.com/docs#random) supports returning floating-point numbers - * [_.runInContext](http://lodash.com/docs#runInContext) for easier mocking - * [_.sortBy](http://lodash.com/docs#sortBy) supports sorting by multiple properties - * [_.support](http://lodash.com/docs#support) for flagging environment features - * [_.template](http://lodash.com/docs#template) supports [*“importsâ€*](http://lodash.com/docs#templateSettings_imports) options & [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals) - * [_.transform](http://lodash.com/docs#transform) as a powerful alternative to [_.reduce](http://lodash.com/docs#reduce) for transforming objects - * [_.where](http://lodash.com/docs#where) supports deep object comparisons - * [_.xor](http://lodash.com/docs#xor) as a companion to [_.difference](http://lodash.com/docs#difference), [_.intersection](http://lodash.com/docs#intersection), & [_.union](http://lodash.com/docs#union) - * [_.zip](http://lodash.com/docs#zip) is capable of unzipping values - * [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), & - [more](http://lodash.com/docs "_.assign, _.clone, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept callbacks - * [_.contains](http://lodash.com/docs#contains), [_.toArray](http://lodash.com/docs#toArray), & - [more](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.forEachRight, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.where") accept strings - * [_.filter](http://lodash.com/docs#filter), [_.map](http://lodash.com/docs#map), & - [more](http://lodash.com/docs "_.countBy, _.every, _.find, _.findKey, _.findLast, _.findLastIndex, _.findLastKey, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluckâ€* & *“_.whereâ€* shorthands - * [_.findLast](http://lodash.com/docs#findLast), [_.findLastIndex](http://lodash.com/docs#findLastIndex), & - [more](http://lodash.com/docs "_.findLastKey, _.forEachRight, _.forInRight, _.forOwnRight, _.partialRight") right-associative methods - -## Resources - - * Podcasts - - [JavaScript Jabber](http://javascriptjabber.com/079-jsj-lo-dash-with-john-david-dalton/) - - * Posts - - [Say “Hello†to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) - - [Custom builds in Lo-Dash 2.0](http://kitcambridge.be/blog/custom-builds-in-lo-dash-2-dot-0/) - - * Videos - - [Introduction](https://vimeo.com/44154599) - - [Origins](https://vimeo.com/44154600) - - [Optimizations & builds](https://vimeo.com/44154601) - - [Native method use](https://vimeo.com/48576012) - - [Testing](https://vimeo.com/45865290) - - [CascadiaJS ’12](http://www.youtube.com/watch?v=dpPy4f_SeEk) - - A list of other community created podcasts, posts, & videos is available on our [wiki](https://github.com/lodash/lodash/wiki/Resources). - -## Support - -Tested in Chrome 5~31, Firefox 2~25, IE 6-11, Opera 9.25~17, Safari 3-7, Node.js 0.6.21~0.10.22, Narwhal 0.3.2, PhantomJS 1.9.2, RingoJS 0.9, & Rhino 1.7RC5.
                  -Automated browser test results [are available](https://saucelabs.com/u/lodash) as well as [Travis CI](https://travis-ci.org/) builds for [lodash](https://travis-ci.org/lodash/lodash/), [lodash-cli](https://travis-ci.org/lodash/lodash-cli/), [lodash-amd](https://travis-ci.org/lodash/lodash-amd/), [lodash-node](https://travis-ci.org/lodash/lodash-node/), & [grunt-lodash](https://travis-ci.org/lodash/grunt-lodash). - -Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
                  -[![Sauce Labs](http://lodash.com/_img/sauce.png)](https://saucelabs.com/ "Sauce Labs: Selenium Testing & More") - -## Installation & usage - -In browsers: - -```html - -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm i --save lodash - -{sudo} npm i -g lodash -npm ln lodash -``` - -In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): - -```js -var _ = require('lodash'); -// or as Underscore -var _ = require('lodash/dist/lodash.underscore'); -``` - -**Notes:** - * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL - * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader: - -```js -require({ - 'packages': [ - { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } - ] -}, -['lodash'], function(_) { - console.log(_.VERSION); -}); -``` - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 23798ba8..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/liftoff/node_modules/findup-sync/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,7157 +0,0 @@ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; - - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = {}; - - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; - - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; - - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; - - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + - - // line terminators - '\n\r\u2028\u2029' + - - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowedProps = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - errorClass = '[object Error]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; - - /** Used as the data object for `iteratorTemplate` */ - var iteratorData = { - 'args': '', - 'array': null, - 'bottom': '', - 'firstArg': '', - 'init': '', - 'keys': null, - 'loop': '', - 'shadowedProps': null, - 'support': null, - 'top': '', - 'useHas': false - }; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; - - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; - } - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } - - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; - - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); - - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; - } - } - } - - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; - - while (++index < length) { - var value = ac[index], - other = bc[index]; - - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; - - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; - - while (++index < length) { - result.push(array[index]); - } - return result; - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } - - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); - } - } - - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); - } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); - } - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ - var arrayRef = []; - - /** Used for native method references */ - var errorProto = Error.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; - - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); - - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; - - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to avoid iterating non-enumerable properties in IE < 9 */ - var nonEnumProps = {}; - nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; - nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; - nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; - nonEnumProps[objectClass] = { 'constructor': true }; - - (function() { - var length = shadowedProps.length; - while (length--) { - var key = shadowedProps[length]; - for (var className in nonEnumProps) { - if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { - nonEnumProps[className][key] = false; - } - } - } - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; - - /** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function() { - var ctor = function() { this.x = 1; }, - object = { '0': 1, 'length': 1 }, - props = []; - - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var key in new ctor) { props.push(key); } - for (key in arguments) { } - - /** - * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsClass = toString.call(arguments) == argsClass; - - /** - * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). - * - * @memberOf _.support - * @type boolean - */ - support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); - - /** - * Detect if `name` or `message` properties of `Error.prototype` are - * enumerable by default. (IE < 9, Safari < 5.1) - * - * @memberOf _.support - * @type boolean - */ - support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); - - /** - * Detect if `prototype` properties are enumerable by default. - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - * - * @memberOf _.support - * @type boolean - */ - support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if `arguments` object indexes are non-enumerable - * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumArgs = key != 0; - - /** - * Detect if properties shadowing those on `Object.prototype` are non-enumerable. - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumShadows = !/valueOf/.test(props); - - /** - * Detect if own properties are iterated after inherited properties (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.ownLast = props[0] != 'x'; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); - - /** - * Detect lack of support for accessing string characters by index. - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - * - * @memberOf _.support - * @type boolean - */ - support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) - * and that the JS engine errors when attempting to coerce an object to - * a string without a `toString` function. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); - } catch(e) { - support.nodeClass = true; - } - }(1)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Object} data The data object used to populate the text. - * @returns {string} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg) + - ', result = ' + - (obj.init) + - ';\nif (!iterable) return result;\n' + - (obj.top) + - ';'; - if (obj.array) { - __p += '\nvar length = iterable.length; index = -1;\nif (' + - (obj.array) + - ') { '; - if (support.unindexedChars) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } - __p += '\n while (++index < length) {\n ' + - (obj.loop) + - ';\n }\n}\nelse { '; - } else if (support.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop) + - ';\n }\n } else { '; - } - - if (support.enumPrototypes) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } - - if (support.enumErrorProps) { - __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; - } - - var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } - - if (obj.useHas && obj.keys) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; - if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - } else { - __p += '\n for (index in iterable) {\n'; - if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - if (support.nonEnumShadows) { - __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; - for (k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowedProps[k]) + - '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; - if (!obj.useHas) { - __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; - } - __p += ') {\n ' + - (obj.loop) + - ';\n } '; - } - __p += '\n } '; - } - - } - - if (obj.array || support.nonEnumArgs) { - __p += '\n}'; - } - __p += - (obj.bottom) + - ';\nreturn result'; - - return __p - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; - } - else { - result = isArr ? slice(value) : assign({}, value); - } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - // exit for shallow clone - if (!isDeep) { - return result; - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); - }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } - - /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. - */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; - - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(values); - } - return result; - } - - /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. - */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - } - stackA.pop(); - stackB.pop(); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - - /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. - * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. - */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; - - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; - - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; - } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; - } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; - } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); - } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); - } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {...Object} [options] The compile options object(s). - * @param {string} [options.array] Code to determine if the iterable is an array or array-like. - * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. - * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. - * @param {string} [options.args] A comma separated string of iteration function arguments. - * @param {string} [options.top] Code to execute before the iteration branches. - * @param {string} [options.loop] Code to execute in the object loop. - * @param {string} [options.bottom] Code to execute after the iteration branches. - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - // data properties - iteratorData.shadowedProps = shadowedProps; - - // iterator options - iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; - iteratorData.init = 'iterable'; - iteratorData.useHas = true; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - iteratorData[key] = object[key]; - } - } - var args = iteratorData.args; - iteratorData.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + - 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + - 'objectTypes, nonEnumProps, stringClass, stringProto, toString', - 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' - ); - - // return the compiled function - return factory( - baseCreateCallback, errorClass, errorProto, hasOwnProperty, - indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, - objectTypes, nonEnumProps, stringClass, stringProto, toString - ); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || - (!support.argsClass && isArguments(value)) || - (!support.nodeClass && isNode(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (support.ownLast) { - forIn(value, function(value, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (!support.argsClass) { - isArguments = function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; - }; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = createIterator({ - 'args': 'object', - 'init': '[]', - 'top': 'if (!(objectTypes[typeof object])) return result', - 'loop': 'result.push(index)' - }); - - /** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", - 'array': "typeof length == 'number'", - 'keys': keys, - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'keys': keys, - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'array': false - }; - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the callback for each - * element in the collection. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createIterator(eachIteratorOptions); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; - } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } - * }; - * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' - * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' - */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } - * }; - * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' - * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' - */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' - */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); - - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; - } - } - return object; - } - - /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } - } - return object; - } - - /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value && value.nodeType === 1 || false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - (support.argsClass ? className == argsClass : isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value == 'function' && toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; - } - - /** - * Checks if `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * _.isPlainObject(new Shape); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/fred/); - * // => true - */ - function isRegExp(value) { - return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('fred'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } - */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } - * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } - */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } - } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? baseEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); - } - return accumulator; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.contains('pebbles', 'eb'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - baseEach(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - - /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } - * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } - */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - } - - /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 - */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - baseEach(collection, callback, thisArg); - } - return collection; - } - - /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' - */ - function forEachRight(collection, callback, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (support.unindexedChars && isString(collection)) { - iterable = collection.split(''); - } - baseEach(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(iterable[key], key, collection); - }); - } - return collection; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = lodash.createCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; - * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the collection. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] - */ - var pluck = map; - - /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Retrieves a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } else if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] - * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); - } - releaseObject(object); - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (support.unindexedChars && isString(collection)) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] - * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; - * }); - * // => 2 - * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 - */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 - * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 - */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] - */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] - */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; - } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] - */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; - - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); - } - } - releaseArray(caches); - releaseArray(seen); - return result; - } - - /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. - * - * @static - * @memberOf _ - * @category Arrays - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); - * - * console.log(array); - * // => [1, 3, 5] - * - * console.log(evens); - * // => [2, 4, 6] - */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); - } - - /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); - } - - /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. - * - * @static - * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed - */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' - * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; - * - * func(); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } - - /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; - * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; - * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' - */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. - * @example - * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 - * - * curried(1, 2)(3); - * // => 6 - * - * curried(1, 2, 3); - * // => 6 - */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); - * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); - * - * // ensure `batchLog` is executed once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * source.addEventListener('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * }, false); - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - wait = nativeMax(0, wait) || 0; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); - trailing = 'trailing' in options ? options.trailing : trailing; - } - var delayed = function() { - var remaining = wait - (now() - stamp); - if (remaining <= 0) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - }; - - var maxDelayed = function() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - }; - - return function() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - }; - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay execution. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it will be used to determine the cache key for storing the result - * based on the arguments provided to the memoized function. By default, the - * first argument provided to the memoized function is used as the cache key. - * The `func` is executed with the `this` binding of the memoized function. - * The result cache is exposed as the `cache` property on the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - * - * fibonacci(9) - * // => 34 - * - * var data = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // modifying the result cache - * var get = _.memoize(function(name) { return data[name]; }, _.identity); - * get('pebbles'); - * // => { 'name': 'pebbles', 'age': 1 } - * - * get.cache.pebbles.name = 'penelope'; - * get('pebbles'); - * // => { 'name': 'penelope', 'age': 1 } - */ - function memoize(func, resolver) { - if (!isFunction(func)) { - throw new TypeError; - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; - - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - } - memoized.cache = {}; - return memoized; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those provided to the new function. This - * method is similar to `_.bind` except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('fred'); - * // => 'hi fred' - */ - function partial(func) { - return createWrapper(func, 16, slice(arguments, 1)); - } - - /** - * This method is like `_.partial` except that `partial` arguments are - * appended to those provided to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createWrapper(func, 32, null, slice(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` function - * at most once per every `wait` milliseconds. Provide an options object to - * indicate that `func` should be invoked on the leading and/or trailing edge - * of the `wait` timeout. Subsequent calls to the throttled function will - * return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle executions to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - * - * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? options.leading : leading; - trailing = 'trailing' in options ? options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = wait; - debounceOptions.trailing = trailing; - - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Additional arguments provided to the function are appended - * to those provided to the wrapper function. The wrapper is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

                  ' + func(text) + '

                  '; - * }); - * - * p('Fred, Wilma, & Pebbles'); - * // => '

                  Fred, Wilma, & Pebbles

                  ' - */ - function wrap(value, wrapper) { - return createWrapper(wrapper, 16, [value]); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. - * @example - * - * var object = { 'name': 'fred' }; - * var getter = _.constant(object); - * getter() === object; - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ - function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; - - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } - } - return result; - }; - } - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} string The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('Fred, Wilma, & Pebbles'); - * // => 'Fred, Wilma, & Pebbles' - */ - function escape(string) { - return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds function properties of a source object to the destination object. - * If `object` is a function methods will be added to its prototype as well. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Function|Object} [object=lodash] object The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options] The options object. - * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. - * @example - * - * function capitalize(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * - * _.mixin({ 'capitalize': capitalize }); - * _.capitalize('fred'); - * // => 'Fred' - * - * _('fred').capitalize().value(); - * // => 'Fred' - * - * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); - * _('fred').capitalize(); - * // => 'Fred' - */ - function mixin(object, source, options) { - var chain = true, - methodNames = source && functions(source); - - if (!source || (!options && !methodNames.length)) { - if (options == null) { - options = source; - } - ctor = lodashWrapper; - source = object; - object = lodash; - methodNames = functions(source); - } - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - var ctor = object, - isFunc = isFunction(ctor); - - forEach(methodNames, function(methodName) { - var func = object[methodName] = source[methodName]; - if (isFunc) { - ctor.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new ctor(result); - result.__chain__ = chainAll; - } - return result; - }; - } - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - context._ = oldDash; - return this; - } - - /** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ - function noop() { - // no operation performed - } - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var stamp = _.now(); - * _.defer(function() { console.log(_.now() - stamp); }); - * // => logs the number of milliseconds it took for the deferred function to be called - */ - var now = isNative(now = Date.now) && now || function() { - return new Date().getTime(); - }; - - /** - * Converts the given value into an integer of the specified radix. - * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the - * `value` is a hexadecimal, in which case a `radix` of `16` is used. - * - * Note: This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See http://es5.github.io/#E. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} value The value to parse. - * @param {number} [radix] The radix used to interpret the value to parse. - * @returns {number} Returns the new integer value. - * @example - * - * _.parseInt('08'); - * // => 8 - */ - var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` - return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); - }; - - /** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example - * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; - * - * var getName = _.property('name'); - * - * _.map(characters, getName); - * // => ['barney', 'fred'] - * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] - */ - function property(key) { - return function(object) { - return object[key]; - }; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number will be - * returned. If `floating` is truey or either `min` or `max` are floats a - * floating-point number will be returned instead of an integer. - * - * @static - * @memberOf _ - * @category Utilities - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating=false] Specify returning a floating-point number. - * @returns {number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (typeof min == 'boolean' && noMax) { - floating = min; - min = 1; - } - else if (!noMax && typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); - } - return baseRandom(min, max); - } - - /** - * Resolves the value of property `key` on `object`. If `key` is a function - * it will be invoked with the `this` binding of `object` and its result returned, - * else the property value is returned. If `object` is falsey then `undefined` - * is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to resolve. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, key) { - if (object) { - var value = object[key]; - return isFunction(value) ? object[key]() : value; - } - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * For more information on precompiling templates see: - * http://lodash.com/custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} text The template text. - * @param {Object} data The data object used to populate the text. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as local variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [sourceURL] The sourceURL of the template's compiled source. - * @param {string} [variable] The data object variable name. - * @returns {Function|string} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': ' -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm install lodash - -npm install -g lodash -npm link lodash -``` - -To avoid potential issues, update `npm` before installing Lo-Dash: - -```bash -npm install npm -g -``` - -In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): - -```js -var _ = require('lodash'); - -// or as a drop-in replacement for Underscore -var _ = require('lodash/lodash.underscore'); -``` - -**Note:** If Lo-Dash is installed globally, run [`npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before requiring it. - -In [RingoJS v0.7.0-](http://ringojs.org/): - -```js -var _ = require('lodash')._; -``` - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader like [RequireJS](http://requirejs.org/): - -```js -require({ - 'paths': { - 'underscore': 'path/to/lodash' - } -}, -['underscore'], function(_) { - console.log(_.VERSION); -}); -``` - -## Release Notes - -### v1.0.1 - - * Add support for specifying source map URLs in `-p`/`--source-map` build options - * Ensured the second argument passed to `_.assign` is not treated as a `callback` - * Ensured `-p`/`--source-map` build options correctly set the `sourceMappingURL` - * Made `-p`/`--source-map` build options set source map *“sourcesâ€* keys based on the builds performed - * Made `_.defer` use `setImmediate`, in Node.js, when available - * Made `_.where` search arrays for values regardless of their index position - * Removed dead code from `_.template` - -The full changelog is available [here](https://github.com/lodash/lodash/wiki/Changelog). - -## BestieJS - -Lo-Dash is part of the [BestieJS](https://github.com/bestiejs) *“Best in Classâ€* module collection. This means we promote solid browser/environment support, ES5 precedents, unit testing, and plenty of documentation. - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](http://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](http://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](http://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://iceddev.com/) | [Kit Cambridge](http://kitcambridge.github.io/) | [Mathias Bynens](http://mathiasbynens.be/) | diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 37ebc920..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/node_modules/globule/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,5152 +0,0 @@ -/** - * @license - * Lo-Dash 1.0.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.4.4 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. - * Available under MIT license - */ -;(function(window, undefined) { - - /** Detect free variable `exports` */ - var freeExports = typeof exports == 'object' && exports; - - /** Detect free variable `module` */ - var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; - - /** Detect free variable `global` and use it as `window` */ - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal) { - window = freeGlobal; - } - - /** Used for array and object method references */ - var arrayRef = [], - objectRef = {}; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = objectRef; - - /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */ - var largeArraySize = 30; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = window._; - - /** Used to match HTML entities */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g; - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - (objectRef.valueOf + '') - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/valueOf|for [^\]]+/g, '.+?') + '$' - ); - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6 - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to match HTML characters */ - var reUnescapedHtml = /[&<>"']/g; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowed = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** Native method shortcuts */ - var ceil = Math.ceil, - concat = arrayRef.concat, - floor = Math.floor, - getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectRef.hasOwnProperty, - push = arrayRef.push, - toString = objectRef.toString; - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind, - nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = window.isFinite, - nativeIsNaN = window.isNaN, - nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeRandom = Math.random; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Detect various environments */ - var isIeOpera = !!window.attachEvent, - isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera); - - /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */ - var isBindFast = nativeBind && !isV8; - - /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */ - var isKeysFast = nativeKeys && (isIeOpera || isV8); - - /** - * Detect the JScript [[DontEnum]] bug: - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well. - */ - var hasDontEnumBug; - - /** - * Detect if a `prototype` properties are enumerable by default: - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - */ - var hasEnumPrototype; - - /** Detect if own properties are iterated after inherited properties (IE < 9) */ - var iteratesOwnLast; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects - * incorrectly: - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - */ - var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 }, - arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]); - - /** Detect if `arguments` object indexes are non-enumerable (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1) */ - var nonEnumArgs = true; - - (function() { - var props = []; - function ctor() { this.x = 1; } - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var prop in new ctor) { props.push(prop); } - for (prop in arguments) { nonEnumArgs = !prop; } - - hasDontEnumBug = !/valueOf/.test(props); - hasEnumPrototype = ctor.propertyIsEnumerable('prototype'); - iteratesOwnLast = props[0] != 'x'; - }(1)); - - /** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */ - var argsAreObjects = arguments.constructor == Object; - - /** Detect if `arguments` objects [[Class]] is unresolvable (Firefox < 4, IE < 9) */ - var noArgsClass = !isArguments(arguments); - - /** - * Detect lack of support for accessing string characters by index: - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - */ - var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is unresolvable (IE < 9) - * and that the JS engine won't error when attempting to coerce an object to - * a string without a `toString` function. - */ - try { - var noNodeClass = toString.call(document) == objectClass && !({ 'toString': 0 } + ''); - } catch(e) { } - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object, that wraps the given `value`, to enable method - * chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`, - * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`, - * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`, - * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, - * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, - * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, - * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`, - * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`, - * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`, - * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * passed, otherwise they return unwrapped values. - * - * @name _ - * @constructor - * @category Chaining - * @param {Mixed} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - */ - function lodash(value) { - // exit early if already wrapped, even if wrapped by a different `lodash` constructor - if (value && typeof value == 'object' && value.__wrapped__) { - return value; - } - // allow invoking `lodash` without the `new` operator - if (!(this instanceof lodash)) { - return new lodash(value); - } - this.__wrapped__ = value; - } - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type String - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Obect} data The data object used to populate the text. - * @returns {String} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg ) + - ', result = iterable;\nif (!iterable) return result;\n' + - (obj.top ) + - ';\n'; - if (obj.arrays) { - __p += 'var length = iterable.length; index = -1;\nif (' + - (obj.arrays ) + - ') { '; - if (obj.noCharByIndex) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } ; - __p += '\n while (++index < length) {\n ' + - (obj.loop ) + - '\n }\n}\nelse { '; - } else if (obj.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop ) + - '\n }\n } else { '; - } ; - - if (obj.hasEnumPrototype) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } ; - - if (obj.isKeysFast && obj.useHas) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n '; - if (obj.hasEnumPrototype) { - __p += 'if (!(skipProto && index == \'prototype\')) {\n '; - } ; - __p += - (obj.loop ) + - ''; - if (obj.hasEnumPrototype) { - __p += '}\n'; - } ; - __p += ' } '; - } else { - __p += '\n for (index in iterable) {'; - if (obj.hasEnumPrototype || obj.useHas) { - __p += '\n if ('; - if (obj.hasEnumPrototype) { - __p += '!(skipProto && index == \'prototype\')'; - } if (obj.hasEnumPrototype && obj.useHas) { - __p += ' && '; - } if (obj.useHas) { - __p += 'hasOwnProperty.call(iterable, index)'; - } ; - __p += ') { '; - } ; - __p += - (obj.loop ) + - '; '; - if (obj.hasEnumPrototype || obj.useHas) { - __p += '\n }'; - } ; - __p += '\n } '; - } ; - - if (obj.hasDontEnumBug) { - __p += '\n\n var ctor = iterable.constructor;\n '; - for (var k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowed[k] ) + - '\';\n if ('; - if (obj.shadowed[k] == 'constructor') { - __p += '!(ctor && ctor.prototype === iterable) && '; - } ; - __p += 'hasOwnProperty.call(iterable, index)) {\n ' + - (obj.loop ) + - '\n } '; - } ; - - } ; - - if (obj.arrays || obj.nonEnumArgs) { - __p += '\n}'; - } ; - __p += - (obj.bottom ) + - ';\nreturn result'; - - - return __p - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)", - 'arrays': "typeof length == 'number'", - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'arrays': false - }; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function optimized to search large arrays for a given `value`, - * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`. - * - * @private - * @param {Array} array The array to search. - * @param {Mixed} value The value to search for. - * @param {Number} [fromIndex=0] The index to search from. - * @param {Number} [largeSize=30] The length at which an array is considered large. - * @returns {Boolean} Returns `true`, if `value` is found, else `false`. - */ - function cachedContains(array, fromIndex, largeSize) { - fromIndex || (fromIndex = 0); - - var length = array.length, - isLarge = (length - fromIndex) >= (largeSize || largeArraySize); - - if (isLarge) { - var cache = {}, - index = fromIndex - 1; - - while (++index < length) { - // manually coerce `value` to a string because `hasOwnProperty`, in some - // older versions of Firefox, coerces objects incorrectly - var key = array[index] + ''; - (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]); - } - } - return function(value) { - if (isLarge) { - var key = value + ''; - return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1; - } - return indexOf(array, value, fromIndex) > -1; - } - } - - /** - * Used by `_.max` and `_.min` as the default `callback` when a given - * `collection` is a string value. - * - * @private - * @param {String} value The character to inspect. - * @returns {Number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` values, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {Number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ai = a.index, - bi = b.index; - - a = a.criteria; - b = b.criteria; - - // ensure a stable sort in V8 and other engines - // http://code.google.com/p/v8/issues/detail?id=90 - if (a !== b) { - if (a > b || typeof a == 'undefined') { - return 1; - } - if (a < b || typeof b == 'undefined') { - return -1; - } - } - return ai < bi ? -1 : 1; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` binding - * of `thisArg` and prepends any `partialArgs` to the arguments passed to the - * bound function. - * - * @private - * @param {Function|String} func The function to bind or the method name. - * @param {Mixed} [thisArg] The `this` binding of `func`. - * @param {Array} partialArgs An array of arguments to be partially applied. - * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right. - * @returns {Function} Returns the new bound function. - */ - function createBound(func, thisArg, partialArgs, rightIndicator) { - var isFunc = isFunction(func), - isPartial = !partialArgs, - key = thisArg; - - // juggle arguments - if (isPartial) { - partialArgs = thisArg; - } - if (!isFunc) { - thisArg = func; - } - - function bound() { - // `Function#bind` spec - // http://es5.github.com/#x15.3.4.5 - var args = arguments, - thisBinding = isPartial ? this : thisArg; - - if (!isFunc) { - func = thisArg[key]; - } - if (partialArgs.length) { - args = args.length - ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args)) - : partialArgs; - } - if (this instanceof bound) { - // ensure `new bound` is an instance of `bound` and `func` - noop.prototype = func.prototype; - thisBinding = new noop; - noop.prototype = null; - - // mimic the constructor's `return` behavior - // http://es5.github.com/#x13.2.2 - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - return bound; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name, the created callback will return the property value for a given element. - * If `func` is an object, the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @private - * @param {Mixed} [func=identity] The value to convert to a callback. - * @param {Mixed} [thisArg] The `this` binding of the created callback. - * @param {Number} [argCount=3] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function createCallback(func, thisArg, argCount) { - if (func == null) { - return identity; - } - var type = typeof func; - if (type != 'function') { - if (type != 'object') { - return function(object) { - return object[func]; - }; - } - var props = keys(func); - return function(object) { - var length = props.length, - result = false; - while (length--) { - if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) { - break; - } - } - return result; - }; - } - if (typeof thisArg != 'undefined') { - if (argCount === 1) { - return function(value) { - return func.call(thisArg, value); - }; - } - if (argCount === 2) { - return function(a, b) { - return func.call(thisArg, a, b); - }; - } - if (argCount === 4) { - return function(accumulator, value, index, object) { - return func.call(thisArg, accumulator, value, index, object); - }; - } - return function(value, index, object) { - return func.call(thisArg, value, index, object); - }; - } - return func; - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {Object} [options1, options2, ...] The compile options object(s). - * arrays - A string of code to determine if the iterable is an array or array-like. - * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop. - * args - A string of comma separated arguments the iteration function will accept. - * top - A string of code to execute before the iteration branches. - * loop - A string of code to execute in the object loop. - * bottom - A string of code to execute after the iteration branches. - * - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - var data = { - // support properties - 'hasDontEnumBug': hasDontEnumBug, - 'hasEnumPrototype': hasEnumPrototype, - 'isKeysFast': isKeysFast, - 'nonEnumArgs': nonEnumArgs, - 'noCharByIndex': noCharByIndex, - 'shadowed': shadowed, - - // iterator options - 'arrays': 'isArray(iterable)', - 'bottom': '', - 'loop': '', - 'top': '', - 'useHas': true - }; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - data[key] = object[key]; - } - } - var args = data.args; - data.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'createCallback, hasOwnProperty, isArguments, isArray, isString, ' + - 'objectTypes, nativeKeys', - 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}' - ); - // return the compiled function - return factory( - createCallback, hasOwnProperty, isArguments, isArray, isString, - objectTypes, nativeKeys - ); - } - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the `callback` for each - * element in the `collection`. The `callback` is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|String} Returns `collection`. - */ - var each = createIterator(eachIteratorOptions); - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {String} match The matched character to escape. - * @returns {String} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {String} match The matched character to escape. - * @returns {String} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * A no-operation function. - * - * @private - */ - function noop() { - // no operation performed - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used, instead of `Array#slice`, to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|String} collection The collection to slice. - * @param {Number} start The start index. - * @param {Number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {String} match The matched character to unescape. - * @returns {String} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return toString.call(value) == argsClass; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (noArgsClass) { - isArguments = function(value) { - return value ? hasOwnProperty.call(value, 'callee') : false; - }; - } - - /** - * Iterates over `object`'s own and inherited enumerable properties, executing - * the `callback` for each property. The `callback` is bound to `thisArg` and - * invoked with three arguments; (value, key, object). Callbacks may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Dog(name) { - * this.name = name; - * } - * - * Dog.prototype.bark = function() { - * alert('Woof, woof!'); - * }; - * - * _.forIn(new Dog('Dagny'), function(value, key) { - * alert(key); - * }); - * // => alerts 'name' and 'bark' (order is not guaranteed) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * Iterates over an object's own enumerable properties, executing the `callback` - * for each property. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by explicitly - * returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * alert(key); - * }); - * // => alerts '0', '1', and 'length' (order is not guaranteed) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - // `instanceof` may cause a memory leak in IE 7 if `value` is a host object - // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak - return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass; - }; - - /** - * Creates an array composed of the own enumerable property names of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (order is not guaranteed) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((hasEnumPrototype && typeof object == 'function') || - (nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** - * A fallback implementation of `isPlainObject` that checks if a given `value` - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - // avoid non-objects and false positives for `arguments` objects - var result = false; - if (!(value && typeof value == 'object') || isArguments(value)) { - return result; - } - // check that the constructor is `Object` (i.e. `Object instanceof Object`) - var ctor = value.constructor; - if ((!isFunction(ctor) && (!noNodeClass || !isNode(value))) || ctor instanceof ctor) { - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (iteratesOwnLast) { - forIn(value, function(value, key, object) { - result = !hasOwnProperty.call(object, key); - return false; - }); - return result === false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return result === false || hasOwnProperty.call(value, result); - } - return result; - } - - /** - * A fallback implementation of `Object.keys` that produces an array of the - * given object's own enumerable property names. - * - * @private - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names. - */ - function shimKeys(object) { - var result = []; - forOwn(object, function(value, key) { - result.push(key); - }); - return result; - } - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite propery assignments of previous - * sources. If a `callback` function is passed, it will be executed to produce - * the assigned values. The `callback` is bound to `thisArg` and invoked with - * two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {Object} [source1, source2, ...] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'moe' }, { 'age': 40 }); - * // => { 'name': 'moe', 'age': 40 } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var food = { 'name': 'apple' }; - * defaults(food, { 'name': 'banana', 'type': 'fruit' }); - * // => { 'name': 'apple', 'type': 'fruit' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `deep` is `true`, nested objects will also - * be cloned, otherwise they will be assigned by reference. If a `callback` - * function is passed, it will be executed to produce the cloned values. If - * `callback` returns `undefined`, cloning will be handled by the method instead. - * The `callback` is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to clone. - * @param {Boolean} [deep=false] A flag to indicate a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @param- {Array} [stackA=[]] Internally used to track traversed source objects. - * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts. - * @returns {Mixed} Returns the cloned `value`. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * var shallow = _.clone(stooges); - * shallow[0] === stooges[0]; - * // => true - * - * var deep = _.clone(stooges, true); - * deep[0] === stooges[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, deep, callback, thisArg, stackA, stackB) { - var result = value; - - // allows working with "Collections" methods without using their `callback` - // argument, `index|key`, for this method's `callback` - if (typeof deep == 'function') { - thisArg = callback; - callback = deep; - deep = false; - } - if (typeof callback == 'function') { - callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1); - result = callback(result); - - var done = typeof result != 'undefined'; - if (!done) { - result = value; - } - } - // inspect [[Class]] - var isObj = isObject(result); - if (isObj) { - var className = toString.call(result); - if (!cloneableClasses[className] || (noNodeClass && isNode(result))) { - return result; - } - var isArr = isArray(result); - } - // shallow clone - if (!isObj || !deep) { - return isObj && !done - ? (isArr ? slice(result) : assign({}, result)) - : result; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return done ? result : new ctor(+result); - - case numberClass: - case stringClass: - return done ? result : new ctor(result); - - case regexpClass: - return done ? result : ctor(result.source, reFlags.exec(result)); - } - // check for circular references and return corresponding clone - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - // init cloned object - if (!done) { - result = isArr ? ctor(result.length) : {}; - - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) { - result[key] = clone(objValue, deep, callback, undefined, stackA, stackB); - }); - - return result; - } - - /** - * Creates a deep clone of `value`. If a `callback` function is passed, it will - * be executed to produce the cloned values. If `callback` returns the value it - * was passed, cloning will be handled by the method instead. The `callback` is - * bound to `thisArg` and invoked with one argument; (value). - * - * Note: This function is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the deep cloned `value`. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * var deep = _.cloneDeep(stooges); - * deep[0] === stooges[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : value; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return clone(value, true, callback, thisArg); - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {Object} [source1, source2, ...] The source objects. - * @param- {Object} [guard] Internally used to allow working with `_.reduce` - * without using its callback's `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var food = { 'name': 'apple' }; - * _.defaults(food, { 'name': 'banana', 'type': 'fruit' }); - * // => { 'name': 'apple', 'type': 'fruit' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * Creates a sorted array of all enumerable properties, own and inherited, - * of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified object `property` exists and is a direct property, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to check. - * @param {String} property The property to check for. - * @returns {Boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, property) { - return object ? hasOwnProperty.call(object, property) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'moe', 'second': 'larry' }); - * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed) - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || toString.call(value) == boolClass; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value instanceof Date || toString.call(value) == dateClass; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value ? value.nodeType === 1 : false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|String} value The value to inspect. - * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - className == argsClass || (noArgsClass && isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If `callback` is passed, it will be executed to - * compare values. If `callback` returns `undefined`, comparisons will be handled - * by the method instead. The `callback` is bound to `thisArg` and invoked with - * two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} a The value to compare. - * @param {Mixed} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @param- {Object} [stackA=[]] Internally used track traversed `a` objects. - * @param- {Object} [stackB=[]] Internally used track traversed `b` objects. - * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`. - * @example - * - * var moe = { 'name': 'moe', 'age': 40 }; - * var copy = { 'name': 'moe', 'age': 40 }; - * - * moe == copy; - * // => false - * - * _.isEqual(moe, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - var whereIndicator = callback === indicatorObject; - if (callback && !whereIndicator) { - callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2); - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - (!a || (type != 'function' && type != 'object')) && - (!b || (otherType != 'function' && otherType != 'object'))) { - return false; - } - // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior - // http://es5.github.com/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return a != +a - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.com/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == b + ''; - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - if (a.__wrapped__ || b.__wrapped__) { - return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (noNodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !argsAreObjects && isArguments(a) ? Object : a.constructor, - ctorB = !argsAreObjects && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && !( - isFunction(ctorA) && ctorA instanceof ctorA && - isFunction(ctorB) && ctorB instanceof ctorB - )) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3) - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - length = a.length; - size = b.length; - - // compare lengths to determine if a deep comparison is necessary - result = size == a.length; - if (!result && !whereIndicator) { - return result; - } - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (whereIndicator) { - while (index--) { - if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) { - break; - } - } - } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) { - break; - } - } - return result; - } - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB)); - } - }); - - if (result && !whereIndicator) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - return result; - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite`, which will return true for - * booleans and empty strings. See http://es5.github.com/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return value instanceof Function || toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.com/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return value ? objectTypes[typeof value] : false; - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN`, which will return `true` for - * `undefined` and other values. See http://es5.github.com/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || toString.call(value) == numberClass; - } - - /** - * Checks if a given `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`. - * @example - * - * function Stooge(name, age) { - * this.name = name; - * this.age = age; - * } - * - * _.isPlainObject(new Stooge('moe', 40)); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'name': 'moe', 'age': 40 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && typeof value == 'object')) { - return false; - } - var valueOf = value.valueOf, - objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value)) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/moe/); - * // => true - */ - function isRegExp(value) { - return value instanceof RegExp || toString.call(value) == regexpClass; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`. - * @example - * - * _.isString('moe'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || toString.call(value) == stringClass; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Mixed} value The value to check. - * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined`, into the destination object. Subsequent sources - * will overwrite propery assignments of previous sources. If a `callback` function - * is passed, it will be executed to produce the merged values of the destination - * and source properties. If `callback` returns `undefined`, merging will be - * handled by the method instead. The `callback` is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {Object} [source1, source2, ...] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @param- {Object} [deepIndicator] Internally used to indicate that `stackA` - * and `stackB` are arrays of traversed objects instead of source objects. - * @param- {Array} [stackA=[]] Internally used to track traversed source objects. - * @param- {Array} [stackB=[]] Internally used to associate values with their - * source counterparts. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'stooges': [ - * { 'name': 'moe' }, - * { 'name': 'larry' } - * ] - * }; - * - * var ages = { - * 'stooges': [ - * { 'age': 40 }, - * { 'age': 50 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object, source, deepIndicator) { - var args = arguments, - index = 0, - length = 2; - - if (!isObject(object)) { - return object; - } - if (deepIndicator === indicatorObject) { - var callback = args[3], - stackA = args[4], - stackB = args[5]; - } else { - stackA = []; - stackB = []; - - // allows working with `_.reduce` and `_.reduceRight` without - // using their `callback` arguments, `index|key` and `collection` - if (typeof deepIndicator != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - callback = createCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - } - while (++index < length) { - (isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - - if (callback) { - result = callback(value, source); - if (typeof result != 'undefined') { - value = result; - } - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!callback) { - value = merge(value, source, indicatorObject, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a `callback` function is passed, it will be executed - * for each property in the `object`, omitting the properties `callback` - * returns truthy for. The `callback` is bound to `thisArg` and invoked - * with three arguments; (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit - * or the function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'moe', 'age': 40 }, 'age'); - * // => { 'name': 'moe' } - * - * _.omit({ 'name': 'moe', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'moe' } - */ - function omit(object, callback, thisArg) { - var isFunc = typeof callback == 'function', - result = {}; - - if (isFunc) { - callback = createCallback(callback, thisArg); - } else { - var props = concat.apply(arrayRef, arguments); - } - forIn(object, function(value, key, object) { - if (isFunc - ? !callback(value, key, object) - : indexOf(props, key, 1) < 0 - ) { - result[key] = value; - } - }); - return result; - } - - /** - * Creates a two dimensional array of the given object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'moe': 30, 'larry': 40 }); - * // => [['moe', 30], ['larry', 40]] (order is not guaranteed) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of property - * names. If `callback` is passed, it will be executed for each property in the - * `object`, picking the properties `callback` returns truthy for. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called - * per iteration or properties to pick, either as individual arguments or arrays. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name'); - * // => { 'name': 'moe' } - * - * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'moe' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = 0, - props = concat.apply(arrayRef, arguments), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = createCallback(callback, thisArg); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns a new array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Array|Number|String} [index1, index2, ...] The indexes of - * `collection` to retrieve, either as individual arguments or arrays. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['moe', 'larry', 'curly'], 0, 2); - * // => ['moe', 'curly'] - */ - function at(collection) { - var index = -1, - props = concat.apply(arrayRef, slice(arguments, 1)), - length = props.length, - result = Array(length); - - if (noCharByIndex && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given `target` element is present in a `collection` using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Mixed} target The value to check for. - * @param {Number} [fromIndex=0] The index to search from. - * @returns {Boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'moe', 'age': 40 }, 'moe'); - * // => true - * - * _.contains('curly', 'ur'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (typeof length == 'number') { - result = (isString(collection) - ? collection.indexOf(target, fromIndex) - : indexOf(collection, target, fromIndex) - ) > -1; - } else { - each(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the given `callback`. The corresponding value of each key - * is the number of times the key was returned by the `callback`. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - function countBy(collection, callback, thisArg) { - var result = {}; - callback = createCallback(callback, thisArg); - - forEach(collection, function(value, key, collection) { - key = callback(value, key, collection) + ''; - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - return result; - } - - /** - * Checks if the `callback` returns a truthy value for **all** elements of a - * `collection`. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Boolean} Returns `true` if all elements pass the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(stooges, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(stooges, { 'age': 50 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = createCallback(callback, thisArg); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - each(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Examines each element in a `collection`, returning an array of all elements - * the `callback` returns truthy for. The `callback` is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(food, 'organic'); - * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }] - * - * // using "_.where" callback shorthand - * _.filter(food, { 'type': 'fruit' }); - * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = createCallback(callback, thisArg); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - each(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Examines each element in a `collection`, returning the first that the `callback` - * returns truthy for. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the element that passed the callback check, - * else `undefined`. - * @example - * - * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => 2 - * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'banana', 'organic': true, 'type': 'fruit' }, - * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } - * ]; - * - * // using "_.where" callback shorthand - * var veggie = _.find(food, { 'type': 'vegetable' }); - * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' } - * - * // using "_.pluck" callback shorthand - * var healthy = _.find(food, 'organic'); - * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' } - */ - function find(collection, callback, thisArg) { - var result; - callback = createCallback(callback, thisArg); - - forEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over a `collection`, executing the `callback` for each element in - * the `collection`. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). Callbacks may exit iteration early - * by explicitly returning `false`. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|String} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(alert).join(','); - * // => alerts each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert); - * // => alerts each number value (order is not guaranteed) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - each(collection, callback, thisArg); - } - return collection; - } - - /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the `callback`. The corresponding value of each key is - * an array of elements passed to `callback` that returned the key. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - function groupBy(collection, callback, thisArg) { - var result = {}; - callback = createCallback(callback, thisArg); - - forEach(collection, function(value, key, collection) { - key = callback(value, key, collection) + ''; - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - return result; - } - - /** - * Invokes the method named by `methodName` on each element in the `collection`, - * returning an array of the results of each invoked method. Additional arguments - * will be passed to each invoked method. If `methodName` is a function, it will - * be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|String} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the `collection` - * through the `callback`. The `callback` is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (order is not guaranteed) - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(stooges, 'name'); - * // => ['moe', 'larry'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = createCallback(callback, thisArg); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - each(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of an `array`. If `callback` is passed, - * it will be executed for each value in the `array` to generate the - * criterion by which the value is ranked. The `callback` is bound to - * `thisArg` and invoked with three arguments; (value, index, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * _.max(stooges, function(stooge) { return stooge.age; }); - * // => { 'name': 'larry', 'age': 50 }; - * - * // using "_.pluck" callback shorthand - * _.max(stooges, 'age'); - * // => { 'name': 'larry', 'age': 50 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - if (!callback && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = !callback && isString(collection) - ? charAtCallback - : createCallback(callback, thisArg); - - each(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of an `array`. If `callback` is passed, - * it will be executed for each value in the `array` to generate the - * criterion by which the value is ranked. The `callback` is bound to `thisArg` - * and invoked with three arguments; (value, index, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * _.min(stooges, function(stooge) { return stooge.age; }); - * // => { 'name': 'moe', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.min(stooges, 'age'); - * // => { 'name': 'moe', 'age': 40 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - if (!callback && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = !callback && isString(collection) - ? charAtCallback - : createCallback(callback, thisArg); - - each(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the `collection`. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {String} property The property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * _.pluck(stooges, 'name'); - * // => ['moe', 'larry'] - */ - var pluck = map; - - /** - * Reduces a `collection` to a value that is the accumulated result of running - * each element in the `collection` through the `callback`, where each successive - * `callback` execution consumes the return value of the previous execution. - * If `accumulator` is not passed, the first element of the `collection` will be - * used as the initial `accumulator` value. The `callback` is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [accumulator] Initial value of the accumulator. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - each(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is similar to `_.reduce`, except that it iterates over a - * `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {Mixed} [accumulator] Initial value of the accumulator. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0, - noaccum = arguments.length < 3; - - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (noCharByIndex && isString(collection)) { - iterable = collection.split(''); - } - callback = createCallback(callback, thisArg, 4); - forEach(collection, function(value, index, collection) { - index = props ? props[--length] : --length; - accumulator = noaccum - ? (noaccum = false, iterable[index]) - : callback(accumulator, iterable[index], index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter`, this method returns the elements of a - * `collection` that `callback` does **not** return truthy for. - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that did **not** pass the - * callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(food, 'organic'); - * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }] - * - * // using "_.where" callback shorthand - * _.reject(food, { 'type': 'fruit' }); - * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }] - */ - function reject(collection, callback, thisArg) { - callback = createCallback(callback, thisArg); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Creates an array of shuffled `array` values, using a version of the - * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = floor(nativeRandom() * (++index + 1)); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to inspect. - * @returns {Number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('curly'); - * // => 5 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the `callback` returns a truthy value for **any** element of a - * `collection`. The function returns as soon as it finds passing value, and - * does not iterate over the entire `collection`. The `callback` is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Boolean} Returns `true` if any element passes the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var food = [ - * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, - * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(food, 'organic'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(food, { 'type': 'meat' }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = createCallback(callback, thisArg); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - each(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in the `collection` through the `callback`. This method - * performs a stable sort, that is, it will preserve the original sort order of - * equal elements. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * // using "_.pluck" callback shorthand - * _.sortBy(['banana', 'strawberry', 'apple'], 'length'); - * // => ['apple', 'banana', 'strawberry'] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = createCallback(callback, thisArg); - forEach(collection, function(value, key, collection) { - result[++index] = { - 'criteria': callback(value, key, collection), - 'index': index, - 'value': value - }; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - result[length] = result[length].value; - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|String} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return noCharByIndex && isString(collection) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Examines each element in a `collection`, returning an array of all elements - * that have the given `properties`. When checking `properties`, this method - * performs a deep comparison between values to determine if they are equivalent - * to each other. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|String} collection The collection to iterate over. - * @param {Object} properties The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given `properties`. - * @example - * - * var stooges = [ - * { 'name': 'moe', 'age': 40 }, - * { 'name': 'larry', 'age': 50 } - * ]; - * - * _.where(stooges, { 'age': 40 }); - * // => [{ 'name': 'moe', 'age': 40 }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values of `array` removed. The values - * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new filtered array. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array of `array` elements not present in the other arrays - * using strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {Array} [array1, array2, ...] Arrays to check. - * @returns {Array} Returns a new array of `array` elements not present in the - * other arrays. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - var index = -1, - length = array ? array.length : 0, - flattened = concat.apply(arrayRef, arguments), - contains = cachedContains(flattened, length), - result = []; - - while (++index < length) { - var value = array[index]; - if (!contains(value)) { - result.push(value); - } - } - return result; - } - - /** - * Gets the first element of the `array`. If a number `n` is passed, the first - * `n` elements of the `array` are returned. If a `callback` function is passed, - * the first elements the `callback` returns truthy for are returned. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|Number|String} [callback|n] The function called - * per element or the number of elements to return. If a property name or - * object is passed, it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var food = [ - * { 'name': 'banana', 'organic': true }, - * { 'name': 'beet', 'organic': false }, - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(food, 'organic'); - * // => [{ 'name': 'banana', 'organic': true }] - * - * var food = [ - * { 'name': 'apple', 'type': 'fruit' }, - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' } - * ]; - * - * // using "_.where" callback shorthand - * _.first(food, { 'type': 'fruit' }); - * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }] - */ - function first(array, callback, thisArg) { - if (array) { - var n = 0, - length = array.length; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = createCallback(callback, thisArg); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array[0]; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `shallow` is - * truthy, `array` will only be flattened a single level. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @param {Boolean} shallow A flag to indicate only flattening a single level. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - */ - function flatten(array, shallow) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - // recursively flatten arrays (susceptible to call stack limits) - if (isArray(value)) { - push.apply(result, shallow ? value : flatten(value)); - } else { - result.push(value); - } - } - return result; - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the `array` is already - * sorted, passing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Mixed} value The value to search for. - * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to - * perform a binary search on a sorted `array`. - * @returns {Number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - var index = -1, - length = array ? array.length : 0; - - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1; - } else if (fromIndex) { - index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Gets all but the last element of `array`. If a number `n` is passed, the - * last `n` elements are excluded from the result. If a `callback` function - * is passed, the last elements the `callback` returns truthy for are excluded - * from the result. The `callback` is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|Number|String} [callback|n=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is passed, it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var food = [ - * { 'name': 'beet', 'organic': false }, - * { 'name': 'carrot', 'organic': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(food, 'organic'); - * // => [{ 'name': 'beet', 'organic': false }] - * - * var food = [ - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' }, - * { 'name': 'carrot', 'type': 'vegetable' } - * ]; - * - * // using "_.where" callback shorthand - * _.initial(food, { 'type': 'vegetable' }); - * // => [{ 'name': 'banana', 'type': 'fruit' }] - */ - function initial(array, callback, thisArg) { - if (!array) { - return []; - } - var n = 0, - length = array.length; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = createCallback(callback, thisArg); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Computes the intersection of all the passed-in arrays using strict equality - * for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} [array1, array2, ...] Arrays to process. - * @returns {Array} Returns a new array of unique elements that are present - * in **all** of the arrays. - * @example - * - * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); - * // => [1, 2] - */ - function intersection(array) { - var args = arguments, - argsLength = args.length, - cache = { '0': {} }, - index = -1, - length = array ? array.length : 0, - isLarge = length >= 100, - result = [], - seen = result; - - outer: - while (++index < length) { - var value = array[index]; - if (isLarge) { - var key = value + ''; - var inited = hasOwnProperty.call(cache[0], key) - ? !(seen = cache[0][key]) - : (seen = cache[0][key] = []); - } - if (inited || indexOf(seen, value) < 0) { - if (isLarge) { - seen.push(value); - } - var argsIndex = argsLength; - while (--argsIndex) { - if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex], 0, 100)))(value)) { - continue outer; - } - } - result.push(value); - } - } - return result; - } - - /** - * Gets the last element of the `array`. If a number `n` is passed, the last - * `n` elements of the `array` are returned. If a `callback` function is passed, - * the last elements the `callback` returns truthy for are returned. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index, array). - * - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|Number|String} [callback|n] The function called - * per element or the number of elements to return. If a property name or - * object is passed, it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Mixed} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var food = [ - * { 'name': 'beet', 'organic': false }, - * { 'name': 'carrot', 'organic': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.last(food, 'organic'); - * // => [{ 'name': 'carrot', 'organic': true }] - * - * var food = [ - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' }, - * { 'name': 'carrot', 'type': 'vegetable' } - * ]; - * - * // using "_.where" callback shorthand - * _.last(food, { 'type': 'vegetable' }); - * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }] - */ - function last(array, callback, thisArg) { - if (array) { - var n = 0, - length = array.length; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = createCallback(callback, thisArg); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array[length - 1]; - } - } - return slice(array, nativeMax(0, length - n)); - } - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Mixed} value The value to search for. - * @param {Number} [fromIndex=array.length-1] The index to search from. - * @returns {Number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Pass either - * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or - * two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.object(['moe', 'larry'], [30, 40]); - * // => { 'moe': 30, 'larry': 40 } - */ - function object(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else { - result[key[0]] = key[1]; - } - } - return result; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Number} [start=0] The start of the range. - * @param {Number} end The end of the range. - * @param {Number} [step=1] The value to increment or descrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(10); - * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - * - * _.range(1, 11); - * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - * - * _.range(0, 30, 5); - * // => [0, 5, 10, 15, 20, 25] - * - * _.range(0, -10, -1); - * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = +step || 1; - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so V8 will avoid the slower "dictionary" mode - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / step)), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * The opposite of `_.initial`, this method gets all but the first value of `array`. - * If a number `n` is passed, the first `n` values are excluded from the result. - * If a `callback` function is passed, the first elements the `callback` returns - * truthy for are excluded from the result. The `callback` is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|Number|String} [callback|n=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is passed, it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var food = [ - * { 'name': 'banana', 'organic': true }, - * { 'name': 'beet', 'organic': false }, - * ]; - * - * // using "_.pluck" callback shorthand - * _.rest(food, 'organic'); - * // => [{ 'name': 'beet', 'organic': false }] - * - * var food = [ - * { 'name': 'apple', 'type': 'fruit' }, - * { 'name': 'banana', 'type': 'fruit' }, - * { 'name': 'beet', 'type': 'vegetable' } - * ]; - * - * // using "_.where" callback shorthand - * _.rest(food, { 'type': 'fruit' }); - * // => [{ 'name': 'beet', 'type': 'vegetable' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = createCallback(callback, thisArg); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which the `value` - * should be inserted into `array` in order to maintain the sort order of the - * sorted `array`. If `callback` is passed, it will be executed for `value` and - * each element in `array` to compute their sort ranking. The `callback` is - * bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to iterate over. - * @param {Mixed} value The value to evaluate. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Number} Returns the index at which the value should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - callback(array[mid]) < value - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Computes the union of the passed-in arrays using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} [array1, array2, ...] Arrays to process. - * @returns {Array} Returns a new array of unique values, in order, that are - * present in one or more of the arrays. - * @example - * - * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); - * // => [1, 2, 3, 101, 10] - */ - function union() { - return uniq(concat.apply(arrayRef, arguments)); - } - - /** - * Creates a duplicate-value-free version of the `array` using strict equality - * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true` - * for `isSorted` will run a faster algorithm. If `callback` is passed, each - * element of `array` is passed through a callback` before uniqueness is computed. - * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is passed for `callback`, the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is passed for `callback`, the created "_.where" style callback - * will return `true` for elements that have the propeties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted. - * @param {Function|Object|String} [callback=identity] The function called per - * iteration. If a property name or object is passed, it will be used to create - * a "_.pluck" or "_.where" style callback, respectively. - * @param {Mixed} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); }); - * // => [1, 2, 3] - * - * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = [], - seen = result; - - // juggle arguments - if (typeof isSorted == 'function') { - thisArg = callback; - callback = isSorted; - isSorted = false; - } - // init value cache for large arrays - var isLarge = !isSorted && length >= 75; - if (isLarge) { - var cache = {}; - } - if (callback) { - seen = []; - callback = createCallback(callback, thisArg); - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isLarge) { - var key = computed + ''; - var inited = hasOwnProperty.call(cache, key) - ? !(seen = cache[key]) - : (seen = cache[key] = []); - } - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : inited || indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * Creates an array with all occurrences of the passed values removed using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {Mixed} [value1, value2, ...] Values to remove. - * @returns {Array} Returns a new filtered array. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - var index = -1, - length = array ? array.length : 0, - contains = cachedContains(arguments, 1), - result = []; - - while (++index < length) { - var value = array[index]; - if (!contains(value)) { - result.push(value); - } - } - return result; - } - - /** - * Groups the elements of each array at their corresponding indexes. Useful for - * separate data sources that are coordinated through matching array indexes. - * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix - * in a similar fashion. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} [array1, array2, ...] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['moe', 'larry'], [30, 40], [true, false]); - * // => [['moe', 30, true], ['larry', 40, false]] - */ - function zip(array) { - var index = -1, - length = array ? max(pluck(arguments, 'length')) : 0, - result = Array(length); - - while (++index < length) { - result[index] = pluck(arguments, index); - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that is restricted to executing `func` only after it is - * called `n` times. The `func` is executed with the `this` binding of the - * created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Number} n The number of times the function must be called before - * it is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var renderNotes = _.after(notes.length, render); - * _.forEach(notes, function(note) { - * note.asyncSave({ 'success': renderNotes }); - * }); - * // `renderNotes` is run once, after all notes have saved - */ - function after(n, func) { - if (n < 1) { - return func(); - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * passed to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {Mixed} [thisArg] The `this` binding of `func`. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'moe' }, 'hi'); - * func(); - * // => 'hi moe' - */ - function bind(func, thisArg) { - // use `Function#bind` if it exists and is fast - // (in V8 `Function#bind` is slower except when partially applied) - return isBindFast || (nativeBind && arguments.length > 2) - ? nativeBind.call.apply(nativeBind, arguments) - : createBound(func, thisArg, slice(arguments, 2)); - } - - /** - * Binds methods on `object` to `object`, overwriting the existing method. - * Method names may be specified as individual arguments or as arrays of method - * names. If no method names are provided, all the function properties of `object` - * will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {String} [methodName1, methodName2, ...] Method names on the object to bind. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { alert('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => alerts 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = concat.apply(arrayRef, arguments), - index = funcs.length > 1 ? 0 : (funcs = functions(object), -1), - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = bind(object[key], object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those passed to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {String} key The key of the method. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'moe', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi moe' - * - * object.greet = function(greeting) { - * return greeting + ', ' + this.name + '!'; - * }; - * - * func(); - * // => 'hi, moe!' - */ - function bindKey(object, key) { - return createBound(object, key, slice(arguments, 2)); - } - - /** - * Creates a function that is the composition of the passed functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} [func1, func2, ...] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var greet = function(name) { return 'hi ' + name; }; - * var exclaim = function(statement) { return statement + '!'; }; - * var welcome = _.compose(exclaim, greet); - * welcome('moe'); - * // => 'hi moe!' - */ - function compose() { - var funcs = arguments; - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. Pass - * `true` for `immediate` to cause debounce to invoke `func` on the leading, - * instead of the trailing, edge of the `wait` timeout. Subsequent calls to - * the debounced function will return the result of the last `func` call. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {Number} wait The number of milliseconds to delay. - * @param {Boolean} immediate A flag to indicate execution is on the leading - * edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * var lazyLayout = _.debounce(calculateLayout, 300); - * jQuery(window).on('resize', lazyLayout); - */ - function debounce(func, wait, immediate) { - var args, - result, - thisArg, - timeoutId; - - function delayed() { - timeoutId = null; - if (!immediate) { - result = func.apply(thisArg, args); - } - } - return function() { - var isImmediate = immediate && !timeoutId; - args = arguments; - thisArg = this; - - clearTimeout(timeoutId); - timeoutId = setTimeout(delayed, wait); - - if (isImmediate) { - result = func.apply(thisArg, args); - } - return result; - }; - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be passed to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {Number} wait The number of milliseconds to delay execution. - * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. - * @returns {Number} Returns the `setTimeout` timeout id. - * @example - * - * var log = _.bind(console.log, console); - * _.delay(log, 1000, 'logged later'); - * // => 'logged later' (Appears after one second.) - */ - function delay(func, wait) { - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be passed to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. - * @returns {Number} Returns the `setTimeout` timeout id. - * @example - * - * _.defer(function() { alert('deferred'); }); - * // returns from the function before `alert` is called - */ - function defer(func) { - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - // use `setImmediate` if it's available in Node.js - if (isV8 && freeModule && typeof setImmediate == 'function') { - defer = bind(setImmediate, window); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * passed, it will be used to determine the cache key for storing the result - * based on the arguments passed to the memoized function. By default, the first - * argument passed to the memoized function is used as the cache key. The `func` - * is executed with the `this` binding of the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - */ - function memoize(func, resolver) { - var cache = {}; - return function() { - var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + ''; - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - }; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those passed to the new function. This - * method is similar to `_.bind`, except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('moe'); - * // => 'hi moe' - */ - function partial(func) { - return createBound(func, slice(arguments, 1)); - } - - /** - * This method is similar to `_.partial`, except that `partial` arguments are - * appended to those passed to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createBound(func, slice(arguments, 1), null, indicatorObject); - } - - /** - * Creates a function that, when executed, will only call the `func` - * function at most once per every `wait` milliseconds. If the throttled - * function is invoked more than once during the `wait` timeout, `func` will - * also be called on the trailing edge of the timeout. Subsequent calls to the - * throttled function will return the result of the last `func` call. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {Number} wait The number of milliseconds to throttle executions to. - * @returns {Function} Returns the new throttled function. - * @example - * - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - */ - function throttle(func, wait) { - var args, - result, - thisArg, - timeoutId, - lastCalled = 0; - - function trailingCall() { - lastCalled = new Date; - timeoutId = null; - result = func.apply(thisArg, args); - } - return function() { - var now = new Date, - remaining = wait - (now - lastCalled); - - args = arguments; - thisArg = this; - - if (remaining <= 0) { - clearTimeout(timeoutId); - timeoutId = null; - lastCalled = now; - result = func.apply(thisArg, args); - } - else if (!timeoutId) { - timeoutId = setTimeout(trailingCall, remaining); - } - return result; - }; - } - - /** - * Creates a function that passes `value` to the `wrapper` function as its - * first argument. Additional arguments passed to the function are appended - * to those passed to the `wrapper` function. The `wrapper` is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Mixed} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var hello = function(name) { return 'hello ' + name; }; - * hello = _.wrap(hello, function(func) { - * return 'before, ' + func('moe') + ', after'; - * }); - * hello(); - * // => 'before, hello moe, after' - */ - function wrap(value, wrapper) { - return function() { - var args = [value]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {String} string The string to escape. - * @returns {String} Returns the escaped string. - * @example - * - * _.escape('Moe, Larry & Curly'); - * // => 'Moe, Larry & Curly' - */ - function escape(string) { - return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This function returns the first argument passed to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Mixed} value Any value. - * @returns {Mixed} Returns `value`. - * @example - * - * var moe = { 'name': 'moe' }; - * moe === _.identity(moe); - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds functions properties of `object` to the `lodash` function and chainable - * wrapper. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object of function properties to add to `lodash`. - * @example - * - * _.mixin({ - * 'capitalize': function(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * }); - * - * _.capitalize('moe'); - * // => 'Moe' - * - * _('moe').capitalize(); - * // => 'Moe' - */ - function mixin(object) { - forEach(functions(object), function(methodName) { - var func = lodash[methodName] = object[methodName]; - - lodash.prototype[methodName] = function() { - var args = [this.__wrapped__]; - push.apply(args, arguments); - return new lodash(func.apply(lodash, args)); - }; - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - window._ = oldDash; - return this; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is passed, a number between `0` and the given number will be returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Number} [min=0] The minimum possible value. - * @param {Number} [max=1] The maximum possible value. - * @returns {Number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => a number between 0 and 5 - * - * _.random(5); - * // => also a number between 0 and 5 - */ - function random(min, max) { - if (min == null && max == null) { - max = 1; - } - min = +min || 0; - if (max == null) { - max = min; - min = 0; - } - return min + floor(nativeRandom() * ((+max || 0) - min + 1)); - } - - /** - * Resolves the value of `property` on `object`. If `property` is a function, - * it will be invoked and its result returned, else the property value is - * returned. If `object` is falsey, then `null` is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {String} property The property to get the value of. - * @returns {Mixed} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, property) { - var value = object ? object[property] : undefined; - return isFunction(value) ? object[property]() : value; - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp` - * build and using precompiled templates, or loading Lo-Dash in a sandbox. - * - * For more information on precompiling templates see: - * http://lodash.com/#custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {String} text The template text. - * @param {Obect} data The data object used to populate the text. - * @param {Object} options The options object. - * escape - The "escape" delimiter regexp. - * evaluate - The "evaluate" delimiter regexp. - * interpolate - The "interpolate" delimiter regexp. - * sourceURL - The sourceURL of the template's compiled source. - * variable - The data object variable name. - * - * @returns {Function|String} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'moe' }); - * // => 'hello moe' - * - * var list = '<% _.forEach(people, function(name) { %>
                1. <%= name %>
                2. <% }); %>'; - * _.template(list, { 'people': ['moe', 'larry'] }); - * // => '
                3. moe
                4. larry
                5. ' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': ' -``` - -Using [`npm`](http://npmjs.org/): - -```bash -npm i --save lodash - -{sudo} npm i -g lodash -npm ln lodash -``` - -In [Node.js](http://nodejs.org/) & [Ringo](http://ringojs.org/): - -```js -var _ = require('lodash'); -// or as Underscore -var _ = require('lodash/dist/lodash.underscore'); -``` - -**Notes:** - * Don’t assign values to [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL - * If Lo-Dash is installed globally, run [`npm ln lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory *before* requiring it - -In [Rhino](http://www.mozilla.org/rhino/): - -```js -load('lodash.js'); -``` - -In an AMD loader: - -```js -require({ - 'packages': [ - { 'name': 'lodash', 'location': 'path/to/lodash', 'main': 'lodash' } - ] -}, -['lodash'], function(_) { - console.log(_.VERSION); -}); -``` - -## Author - -| [![twitter/jdalton](http://gravatar.com/avatar/299a3d891ff1920b69c364d061007043?s=70)](https://twitter.com/jdalton "Follow @jdalton on Twitter") | -|---| -| [John-David Dalton](http://allyoucanleet.com/) | - -## Contributors - -| [![twitter/blainebublitz](http://gravatar.com/avatar/ac1c67fd906c9fecd823ce302283b4c1?s=70)](https://twitter.com/blainebublitz "Follow @BlaineBublitz on Twitter") | [![twitter/kitcambridge](http://gravatar.com/avatar/6662a1d02f351b5ef2f8b4d815804661?s=70)](https://twitter.com/kitcambridge "Follow @kitcambridge on Twitter") | [![twitter/mathias](http://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | -|---|---|---| -| [Blaine Bublitz](http://www.iceddev.com/) | [Kit Cambridge](http://kitcambridge.be/) | [Mathias Bynens](http://mathiasbynens.be/) | - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/lodash/lodash/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.compat.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.compat.js deleted file mode 100644 index 23798ba8..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/lodash/dist/lodash.compat.js +++ /dev/null @@ -1,7157 +0,0 @@ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash -o ./dist/lodash.compat.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; - - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; - - /** Used to generate unique IDs */ - var idCounter = 0; - - /** Used internally to indicate various things */ - var indicatorObject = {}; - - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; - - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; - - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; - - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + - - // line terminators - '\n\r\u2028\u2029' + - - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); - - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; - - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; - - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); - - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; - - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; - - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; - - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; - - /** Used to fix the JScript [[DontEnum]] bug */ - var shadowedProps = [ - 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', - 'toLocaleString', 'toString', 'valueOf' - ]; - - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - errorClass = '[object Error]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; - - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; - - /** Used as the data object for `iteratorTemplate` */ - var iteratorData = { - 'args': '', - 'array': null, - 'bottom': '', - 'firstArg': '', - 'init': '', - 'keys': null, - 'loop': '', - 'shadowedProps': null, - 'support': null, - 'top': '', - 'useHas': false - }; - - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; - - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; - - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; - } - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } - - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; - - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; - } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); - - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; - } - } - } - - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } - - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; - - while (++index < length) { - var value = ac[index], - other = bc[index]; - - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; - } - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; - - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; - - while (++index < length) { - result.push(array[index]); - } - return result; - } - - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } - - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } - - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } - - /** - * Checks if `value` is a DOM node in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. - */ - function isNode(value) { - // IE < 9 presents DOM nodes as `Object` objects except they have `toString` - // methods that are `typeof` "string" and still can coerce nodes to strings - return typeof value.toString != 'function' && typeof (value + '') == 'string'; - } - - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); - } - } - - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); - } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); - } - } - - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; - } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = array[start + index]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** - * Used for `Array` method references. - * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. - */ - var arrayRef = []; - - /** Used for native method references */ - var errorProto = Error.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; - - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; - - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); - - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; - - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); - - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; - - /** Used to avoid iterating non-enumerable properties in IE < 9 */ - var nonEnumProps = {}; - nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; - nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; - nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; - nonEnumProps[objectClass] = { 'constructor': true }; - - (function() { - var length = shadowedProps.length; - while (length--) { - var key = shadowedProps[length]; - for (var className in nonEnumProps) { - if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { - nonEnumProps[className][key] = false; - } - } - } - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. - * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` - * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. - * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. - * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); - } - - /** - * A fast path for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. - */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; - - /** - * An object used to flag environments features. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - (function() { - var ctor = function() { this.x = 1; }, - object = { '0': 1, 'length': 1 }, - props = []; - - ctor.prototype = { 'valueOf': 1, 'y': 1 }; - for (var key in new ctor) { props.push(key); } - for (key in arguments) { } - - /** - * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.argsClass = toString.call(arguments) == argsClass; - - /** - * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). - * - * @memberOf _.support - * @type boolean - */ - support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); - - /** - * Detect if `name` or `message` properties of `Error.prototype` are - * enumerable by default. (IE < 9, Safari < 5.1) - * - * @memberOf _.support - * @type boolean - */ - support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); - - /** - * Detect if `prototype` properties are enumerable by default. - * - * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 - * (if the prototype or a property on the prototype has been set) - * incorrectly sets a function's `prototype` property [[Enumerable]] - * value to `true`. - * - * @memberOf _.support - * @type boolean - */ - support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if `arguments` object indexes are non-enumerable - * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumArgs = key != 0; - - /** - * Detect if properties shadowing those on `Object.prototype` are non-enumerable. - * - * In IE < 9 an objects own properties, shadowing non-enumerable ones, are - * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). - * - * @memberOf _.support - * @type boolean - */ - support.nonEnumShadows = !/valueOf/.test(props); - - /** - * Detect if own properties are iterated after inherited properties (all but IE < 9). - * - * @memberOf _.support - * @type boolean - */ - support.ownLast = props[0] != 'x'; - - /** - * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. - * - * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` - * and `splice()` functions that fail to remove the last element, `value[0]`, - * of array-like objects even though the `length` property is set to `0`. - * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` - * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. - * - * @memberOf _.support - * @type boolean - */ - support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); - - /** - * Detect lack of support for accessing string characters by index. - * - * IE < 8 can't access characters by index and IE 8 can only access - * characters by index on string literals. - * - * @memberOf _.support - * @type boolean - */ - support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; - - /** - * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) - * and that the JS engine errors when attempting to coerce an object to - * a string without a `toString` function. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); - } catch(e) { - support.nodeClass = true; - } - }(1)); - - /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The template used to create iterator functions. - * - * @private - * @param {Object} data The data object used to populate the text. - * @returns {string} Returns the interpolated text. - */ - var iteratorTemplate = function(obj) { - - var __p = 'var index, iterable = ' + - (obj.firstArg) + - ', result = ' + - (obj.init) + - ';\nif (!iterable) return result;\n' + - (obj.top) + - ';'; - if (obj.array) { - __p += '\nvar length = iterable.length; index = -1;\nif (' + - (obj.array) + - ') { '; - if (support.unindexedChars) { - __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; - } - __p += '\n while (++index < length) {\n ' + - (obj.loop) + - ';\n }\n}\nelse { '; - } else if (support.nonEnumArgs) { - __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + - (obj.loop) + - ';\n }\n } else { '; - } - - if (support.enumPrototypes) { - __p += '\n var skipProto = typeof iterable == \'function\';\n '; - } - - if (support.enumErrorProps) { - __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; - } - - var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } - - if (obj.useHas && obj.keys) { - __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; - if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - } else { - __p += '\n for (index in iterable) {\n'; - if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { - __p += ' if (' + - (conditions.join(' && ')) + - ') {\n '; - } - __p += - (obj.loop) + - '; '; - if (conditions.length) { - __p += '\n }'; - } - __p += '\n } '; - if (support.nonEnumShadows) { - __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; - for (k = 0; k < 7; k++) { - __p += '\n index = \'' + - (obj.shadowedProps[k]) + - '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; - if (!obj.useHas) { - __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; - } - __p += ') {\n ' + - (obj.loop) + - ';\n } '; - } - __p += '\n } '; - } - - } - - if (obj.array || support.nonEnumArgs) { - __p += '\n}'; - } - __p += - (obj.bottom) + - ';\nreturn result'; - - return __p - }; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. - */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; - } - else { - result = isArr ? slice(value) : assign({}, value); - } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } - } - // exit for shallow clone - if (!isDeep) { - return result; - } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); - - // recursively populate clone (susceptible to call stack limits) - (isArr ? baseEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); - }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } - - /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. - * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; - } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } - } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - } - return bind(func, thisArg); - } - - /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. - * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. - */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; - } - - /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. - */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; - - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; - } else { - isLarge = false; - } - } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); - } - } - if (isLarge) { - releaseObject(values); - } - return result; - } - - /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. - */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. - * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; - } - } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { - return false; - } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, - ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } - } - var size = 0; - result = true; - - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); - - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); - - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } - } - stackA.pop(); - stackB.pop(); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; - } - - /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } - - /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. - */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. - * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. - */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; - - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; - - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; - } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; - } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; - } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; - } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); - } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); - } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Creates compiled iteration functions. - * - * @private - * @param {...Object} [options] The compile options object(s). - * @param {string} [options.array] Code to determine if the iterable is an array or array-like. - * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. - * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. - * @param {string} [options.args] A comma separated string of iteration function arguments. - * @param {string} [options.top] Code to execute before the iteration branches. - * @param {string} [options.loop] Code to execute in the object loop. - * @param {string} [options.bottom] Code to execute after the iteration branches. - * @returns {Function} Returns the compiled function. - */ - function createIterator() { - // data properties - iteratorData.shadowedProps = shadowedProps; - - // iterator options - iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; - iteratorData.init = 'iterable'; - iteratorData.useHas = true; - - // merge options into a template data object - for (var object, index = 0; object = arguments[index]; index++) { - for (var key in object) { - iteratorData[key] = object[key]; - } - } - var args = iteratorData.args; - iteratorData.firstArg = /^[^,]+/.exec(args)[0]; - - // create the function factory - var factory = Function( - 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + - 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + - 'objectTypes, nonEnumProps, stringClass, stringProto, toString', - 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' - ); - - // return the compiled function - return factory( - baseCreateCallback, errorClass, errorProto, hasOwnProperty, - indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, - objectTypes, nonEnumProps, stringClass, stringProto, toString - ); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || - (!support.argsClass && isArguments(value)) || - (!support.nodeClass && isNode(value))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - if (support.ownLast) { - forIn(value, function(value, key, object) { - result = hasOwnProperty.call(object, key); - return false; - }); - return result !== false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Checks if `value` is an `arguments` object. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. - * @example - * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } - // fallback for browsers that can't detect `arguments` objects by [[Class]] - if (!support.argsClass) { - isArguments = function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; - }; - } - - /** - * Checks if `value` is an array. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. - * @example - * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true - */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = createIterator({ - 'args': 'object', - 'init': '[]', - 'top': 'if (!(objectTypes[typeof object])) return result', - 'loop': 'result.push(index)' - }); - - /** - * Creates an array composed of the own enumerable property names of an object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - * @example - * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { - return shimKeys(object); - } - return nativeKeys(object); - }; - - /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ - var eachIteratorOptions = { - 'args': 'collection, callback, thisArg', - 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", - 'array': "typeof length == 'number'", - 'keys': keys, - 'loop': 'if (callback(iterable[index], index, collection) === false) return result' - }; - - /** Reusable iterator options for `assign` and `defaults` */ - var defaultsIteratorOptions = { - 'args': 'object, source, guard', - 'top': - 'var args = arguments,\n' + - ' argsIndex = 0,\n' + - " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + - 'while (++argsIndex < argsLength) {\n' + - ' iterable = args[argsIndex];\n' + - ' if (iterable && objectTypes[typeof iterable]) {', - 'keys': keys, - 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", - 'bottom': ' }\n}' - }; - - /** Reusable iterator options for `forIn` and `forOwn` */ - var forOwnIteratorOptions = { - 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, - 'array': false - }; - - /** - * Used to convert characters to HTML entities: - * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") - */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /** - * A function compiled to iterate `arguments` objects, arrays, objects, and - * strings consistenly across environments, executing the callback for each - * element in the collection. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index|key, collection). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @private - * @type Function - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createIterator(eachIteratorOptions); - - /*--------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); - * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var assign = createIterator(defaultsIteratorOptions, { - 'top': - defaultsIteratorOptions.top.replace(';', - ';\n' + - "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + - ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + - "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + - ' callback = args[--argsLength];\n' + - '}' - ), - 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' - }); - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) - * }); - * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; - } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false - * - * var view = { - * 'label': 'docs', - * 'node': element - * }; - * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); - * - * clone.node == view.node; - * // => false - */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. - * @example - * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } - */ - var defaults = createIterator(defaultsIteratorOptions); - - /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } - * }; - * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' - * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' - */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. - * @example - * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } - * }; - * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' - * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' - */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } - - /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { - 'useHas': false - }); - - /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' - */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); - - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; - } - } - return object; - } - - /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * @static - * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example - * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' - */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } - } - return object; - } - - /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example - * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. - * @example - * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example - * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } - */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - result[object[key]] = key; - } - return result; - } - - /** - * Checks if `value` is a boolean value. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. - * @example - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; - } - - /** - * Checks if `value` is a date. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - */ - function isElement(value) { - return value && value.nodeType === 1 || false; - } - - /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. - * @example - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({}); - * // => true - * - * _.isEmpty(''); - * // => true - */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || - (support.argsClass ? className == argsClass : isArguments(value))) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). - * - * @static - * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); - * // => true - * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); - * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true - */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); - } - - /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. - * @example - * - * _.isFinite(-101); - * // => true - * - * _.isFinite('10'); - * // => true - * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); - } - - /** - * Checks if `value` is a function. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - */ - function isFunction(value) { - return typeof value == 'function'; - } - // fallback for older versions of Chrome and Safari - if (isFunction(/x/)) { - isFunction = function(value) { - return typeof value == 'function' && toString.call(value) == funcClass; - }; - } - - /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } - - /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(undefined); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. - * @example - * - * _.isNumber(8.4 * 5); - * // => true - */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; - } - - /** - * Checks if `value` is an object created by the `Object` constructor. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * _.isPlainObject(new Shape); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is a regular expression. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. - * @example - * - * _.isRegExp(/fred/); - * // => true - */ - function isRegExp(value) { - return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example - * - * _.isString('fred'); - * // => true - */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - */ - function isUndefined(value) { - return typeof value == 'undefined'; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } - */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. - * @example - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } - */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; - } - - /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. - * @example - * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } - * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } - */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. - * @example - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } - * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } - */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; - } - - /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] - * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } - } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? baseEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); - } - return accumulator; - } - - /** - * Creates an array composed of the own enumerable property values of `object`. - * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. - * @example - * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) - */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. - * @example - * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] - * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] - */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; - } - - /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. - * - * @static - * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. - * @example - * - * _.contains([1, 2, 3], 1); - * // => true - * - * _.contains([1, 2, 3], 1, 2); - * // => false - * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.contains('pebbles', 'eb'); - * // => true - */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - baseEach(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); - } - return result; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - - /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); - * // => true - * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); - * // => false - */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. - * @example - * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; - } - - /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } - * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } - */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - baseEach(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - } - - /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 - */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } - - /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' - * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) - */ - function forEach(collection, callback, thisArg) { - if (callback && typeof thisArg == 'undefined' && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - baseEach(collection, callback, thisArg); - } - return collection; - } - - /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' - */ - function forEachRight(collection, callback, thisArg) { - var iterable = collection, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - if (typeof length != 'number') { - var props = keys(collection); - length = props.length; - } else if (support.unindexedChars && isString(collection)) { - iterable = collection.split(''); - } - baseEach(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(iterable[key], key, collection); - }); - } - return collection; - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } - - /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. - * @example - * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] - * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] - */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - callback = lodash.createCallback(callback, thisArg, 3); - if (isArray(collection)) { - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - baseEach(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); - } - return result; - } - - /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; - * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; - */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; - * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; - */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - baseEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } - - /** - * Retrieves the value of a specified property from all elements in the collection. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] - */ - var pluck = map; - - /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - baseEach(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } - - /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. - * @example - * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. - * @example - * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] - * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] - */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } - - /** - * Retrieves a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } else if (support.unindexedChars && isString(collection)) { - collection = collection.split(''); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. - * @example - * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] - */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; - } - - /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. - * @example - * - * _.size([1, 2]); - * // => 2 - * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); - * // => 3 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; - } - - /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); - * // => true - * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false - */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } - } - } else { - baseEach(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); - } - return !!result; - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. - * @example - * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] - * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] - */ - function sortBy(collection, callback, thisArg) { - var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); - - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); - } - releaseObject(object); - } - return result; - } - - /** - * Converts the `collection` to an array. - * - * @static - * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. - * @example - * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] - */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return (support.unindexedChars && isString(collection)) - ? collection.split('') - : slice(collection); - } - return values(collection); - } - - /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. - * - * @static - * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] - * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] - */ - var where = filter; - - /*--------------------------------------------------------------------------*/ - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] - */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; - * }); - * // => 2 - * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 - */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 - * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 - * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 - */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } - } - return -1; - } - - /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] - */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } - } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); - } - - /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. - * @example - * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; - * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; - * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] - */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; - } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } - - /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 - * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 4 - * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; - } - return baseIndexOf(array, value, fromIndex); - } - - /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] - */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; - } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); - } - - /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. - * @example - * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] - */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; - - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } - } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); - } - } - releaseArray(caches); - releaseArray(seen); - return result; - } - - /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); - } - - /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - * @example - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. - * - * @static - * @memberOf _ - * @category Arrays - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - function range(start, end, step) { - start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { - end = start; - start = 0; - } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; - } - - /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); - * - * console.log(array); - * // => [1, 3, 5] - * - * console.log(evens); - * // => [2, 4, 6] - */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; - } - } - return result; - } - - /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] - * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] - * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] - */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); - } - - /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 - */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; - } - - /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. - * @example - * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] - */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); - } - - /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. - * @example - * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); - } - - /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] - */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); - } - - /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. - * - * @static - * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. - * @example - * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] - * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); - - while (++index < length) { - result[index] = pluck(array, index); - } - return result; - } - - /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. - * - * @static - * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. - * @example - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. - * - * @static - * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed - */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; - * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' - */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); - } - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked - */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); - } - return object; - } - - /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. - * - * @static - * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' - * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; - * - * func(); - * // => 'hiya fred!' - */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } - - /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. - * - * @static - * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. - * @example - * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; - * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; - * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' - */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } - - /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. - * @example - * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 - * - * curried(1, 2)(3); - * // => 6 - * - * curried(1, 2, 3); - * // => 6 - */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); - } - - /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); - * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); - * - * // ensure `batchLog` is executed once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * source.addEventListener('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * }, false); - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - wait = nativeMax(0, wait) || 0; - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); - trailing = 'trailing' in options ? options.trailing : trailing; - } - var delayed = function() { - var remaining = wait - (now() - stamp); - if (remaining <= 0) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - }; - - var maxDelayed = function() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - }; - - return function() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - }; - } - - /** - * Defers executing the `func` function until the current call stack has cleared. - * Additional arguments will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to defer. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { console.log(text); }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - function defer(func) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 1); - return setTimeout(function() { func.apply(undefined, args); }, 1); - } - - /** - * Executes the `func` function after `wait` milliseconds. Additional arguments - * will be provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay execution. - * @param {...*} [arg] Arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { console.log(text); }, 1000, 'later'); - * // => logs 'later' after one second - */ - function delay(func, wait) { - if (!isFunction(func)) { - throw new TypeError; - } - var args = slice(arguments, 2); - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it will be used to determine the cache key for storing the result - * based on the arguments provided to the memoized function. By default, the - * first argument provided to the memoized function is used as the cache key. - * The `func` is executed with the `this` binding of the memoized function. - * The result cache is exposed as the `cache` property on the memoized function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] A function used to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var fibonacci = _.memoize(function(n) { - * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); - * }); - * - * fibonacci(9) - * // => 34 - * - * var data = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; - * - * // modifying the result cache - * var get = _.memoize(function(name) { return data[name]; }, _.identity); - * get('pebbles'); - * // => { 'name': 'pebbles', 'age': 1 } - * - * get.cache.pebbles.name = 'penelope'; - * get('pebbles'); - * // => { 'name': 'penelope', 'age': 1 } - */ - function memoize(func, resolver) { - if (!isFunction(func)) { - throw new TypeError; - } - var memoized = function() { - var cache = memoized.cache, - key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; - - return hasOwnProperty.call(cache, key) - ? cache[key] - : (cache[key] = func.apply(this, arguments)); - } - memoized.cache = {}; - return memoized; - } - - /** - * Creates a function that is restricted to execute `func` once. Repeat calls to - * the function will return the value of the first call. The `func` is executed - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` executes `createApplication` once - */ - function once(func) { - var ran, - result; - - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (ran) { - return result; - } - ran = true; - result = func.apply(this, arguments); - - // clear the `func` variable so the function may be garbage collected - func = null; - return result; - }; - } - - /** - * Creates a function that, when called, invokes `func` with any additional - * `partial` arguments prepended to those provided to the new function. This - * method is similar to `_.bind` except it does **not** alter the `this` binding. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { return greeting + ' ' + name; }; - * var hi = _.partial(greet, 'hi'); - * hi('fred'); - * // => 'hi fred' - */ - function partial(func) { - return createWrapper(func, 16, slice(arguments, 1)); - } - - /** - * This method is like `_.partial` except that `partial` arguments are - * appended to those provided to the new function. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var defaultsDeep = _.partialRight(_.merge, _.defaults); - * - * var options = { - * 'variable': 'data', - * 'imports': { 'jq': $ } - * }; - * - * defaultsDeep(options, _.templateSettings); - * - * options.variable - * // => 'data' - * - * options.imports - * // => { '_': _, 'jq': $ } - */ - function partialRight(func) { - return createWrapper(func, 32, null, slice(arguments, 1)); - } - - /** - * Creates a function that, when executed, will only call the `func` function - * at most once per every `wait` milliseconds. Provide an options object to - * indicate that `func` should be invoked on the leading and/or trailing edge - * of the `wait` timeout. Subsequent calls to the throttled function will - * return the result of the last `func` call. - * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * @static - * @memberOf _ - * @category Functions - * @param {Function} func The function to throttle. - * @param {number} wait The number of milliseconds to throttle executions to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * var throttled = _.throttle(updatePosition, 100); - * jQuery(window).on('scroll', throttled); - * - * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (!isFunction(func)) { - throw new TypeError; - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? options.leading : leading; - trailing = 'trailing' in options ? options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = wait; - debounceOptions.trailing = trailing; - - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Additional arguments provided to the function are appended - * to those provided to the wrapper function. The wrapper is executed with - * the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Functions - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

                  ' + func(text) + '

                  '; - * }); - * - * p('Fred, Wilma, & Pebbles'); - * // => '

                  Fred, Wilma, & Pebbles

                  ' - */ - function wrap(value, wrapper) { - return createWrapper(wrapper, 16, [value]); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new function. - * @example - * - * var object = { 'name': 'fred' }; - * var getter = _.constant(object); - * getter() === object; - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Produces a callback bound to an optional `thisArg`. If `func` is a property - * name the created callback will return the property value for a given element. - * If `func` is an object the created callback will return `true` for elements - * that contain the equivalent object properties, otherwise it will return `false`. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. - * @example - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // wrap to create custom callback shorthands - * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { - * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); - * return !match ? func(callback, thisArg) : function(object) { - * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; - * }; - * }); - * - * _.filter(characters, 'age__gt38'); - * // => [{ 'name': 'fred', 'age': 40 }] - */ - function createCallback(func, thisArg, argCount) { - var type = typeof func; - if (func == null || type == 'function') { - return baseCreateCallback(func, thisArg, argCount); - } - // handle "_.pluck" style callback shorthands - if (type != 'object') { - return property(func); - } - var props = keys(func), - key = props[0], - a = func[key]; - - // handle "_.where" style callback shorthands - if (props.length == 1 && a === a && !isObject(a)) { - // fast path the common case of providing an object with a single - // property containing a primitive value - return function(object) { - var b = object[key]; - return a === b && (a !== 0 || (1 / a == 1 / b)); - }; - } - return function(object) { - var length = props.length, - result = false; - - while (length--) { - if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { - break; - } - } - return result; - }; - } - - /** - * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their - * corresponding HTML entities. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} string The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('Fred, Wilma, & Pebbles'); - * // => 'Fred, Wilma, & Pebbles' - */ - function escape(string) { - return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); - } - - /** - * This method returns the first argument provided to it. - * - * @static - * @memberOf _ - * @category Utilities - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'name': 'fred' }; - * _.identity(object) === object; - * // => true - */ - function identity(value) { - return value; - } - - /** - * Adds function properties of a source object to the destination object. - * If `object` is a function methods will be added to its prototype as well. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Function|Object} [object=lodash] object The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options] The options object. - * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. - * @example - * - * function capitalize(string) { - * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); - * } - * - * _.mixin({ 'capitalize': capitalize }); - * _.capitalize('fred'); - * // => 'Fred' - * - * _('fred').capitalize().value(); - * // => 'Fred' - * - * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); - * _('fred').capitalize(); - * // => 'Fred' - */ - function mixin(object, source, options) { - var chain = true, - methodNames = source && functions(source); - - if (!source || (!options && !methodNames.length)) { - if (options == null) { - options = source; - } - ctor = lodashWrapper; - source = object; - object = lodash; - methodNames = functions(source); - } - if (options === false) { - chain = false; - } else if (isObject(options) && 'chain' in options) { - chain = options.chain; - } - var ctor = object, - isFunc = isFunction(ctor); - - forEach(methodNames, function(methodName) { - var func = object[methodName] = source[methodName]; - if (isFunc) { - ctor.prototype[methodName] = function() { - var chainAll = this.__chain__, - value = this.__wrapped__, - args = [value]; - - push.apply(args, arguments); - var result = func.apply(object, args); - if (chain || chainAll) { - if (value === result && isObject(result)) { - return this; - } - result = new ctor(result); - result.__chain__ = chainAll; - } - return result; - }; - } - }); - } - - /** - * Reverts the '_' variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @memberOf _ - * @category Utilities - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - context._ = oldDash; - return this; - } - - /** - * A no-operation function. - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var object = { 'name': 'fred' }; - * _.noop(object) === undefined; - * // => true - */ - function noop() { - // no operation performed - } - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Utilities - * @example - * - * var stamp = _.now(); - * _.defer(function() { console.log(_.now() - stamp); }); - * // => logs the number of milliseconds it took for the deferred function to be called - */ - var now = isNative(now = Date.now) && now || function() { - return new Date().getTime(); - }; - - /** - * Converts the given value into an integer of the specified radix. - * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the - * `value` is a hexadecimal, in which case a `radix` of `16` is used. - * - * Note: This method avoids differences in native ES3 and ES5 `parseInt` - * implementations. See http://es5.github.io/#E. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} value The value to parse. - * @param {number} [radix] The radix used to interpret the value to parse. - * @returns {number} Returns the new integer value. - * @example - * - * _.parseInt('08'); - * // => 8 - */ - var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { - // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` - return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); - }; - - /** - * Creates a "_.pluck" style function, which returns the `key` value of a - * given object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} key The name of the property to retrieve. - * @returns {Function} Returns the new function. - * @example - * - * var characters = [ - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 36 } - * ]; - * - * var getName = _.property('name'); - * - * _.map(characters, getName); - * // => ['barney', 'fred'] - * - * _.sortBy(characters, getName); - * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] - */ - function property(key) { - return function(object) { - return object[key]; - }; - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number will be - * returned. If `floating` is truey or either `min` or `max` are floats a - * floating-point number will be returned instead of an integer. - * - * @static - * @memberOf _ - * @category Utilities - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating=false] Specify returning a floating-point number. - * @returns {number} Returns a random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (typeof min == 'boolean' && noMax) { - floating = min; - min = 1; - } - else if (!noMax && typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); - } - return baseRandom(min, max); - } - - /** - * Resolves the value of property `key` on `object`. If `key` is a function - * it will be invoked with the `this` binding of `object` and its result returned, - * else the property value is returned. If `object` is falsey then `undefined` - * is returned. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to resolve. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { - * 'cheese': 'crumpets', - * 'stuff': function() { - * return 'nonsense'; - * } - * }; - * - * _.result(object, 'cheese'); - * // => 'crumpets' - * - * _.result(object, 'stuff'); - * // => 'nonsense' - */ - function result(object, key) { - if (object) { - var value = object[key]; - return isFunction(value) ? object[key]() : value; - } - } - - /** - * A micro-templating method that handles arbitrary delimiters, preserves - * whitespace, and correctly escapes quotes within interpolated code. - * - * Note: In the development build, `_.template` utilizes sourceURLs for easier - * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl - * - * For more information on precompiling templates see: - * http://lodash.com/custom-builds - * - * For more information on Chrome extension sandboxes see: - * http://developer.chrome.com/stable/extensions/sandboxingEval.html - * - * @static - * @memberOf _ - * @category Utilities - * @param {string} text The template text. - * @param {Object} data The data object used to populate the text. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as local variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [sourceURL] The sourceURL of the template's compiled source. - * @param {string} [variable] The data object variable name. - * @returns {Function|string} Returns a compiled function when no `data` object - * is given, else it returns the interpolated text. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= name %>'); - * compiled({ 'name': 'fred' }); - * // => 'hello fred' - * - * // using the "escape" delimiter to escape HTML in data property values - * _.template('<%- value %>', { 'value': ' - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.css b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7cd..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.js deleted file mode 100644 index ef51e038..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/prettify.js +++ /dev/null @@ -1 +0,0 @@ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.html deleted file mode 100644 index ef3bcc4f..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.html +++ /dev/null @@ -1,350 +0,0 @@ - - - - Code coverage report for vinyl/ - - - - - - - -
                  -

                  Code coverage report for vinyl/

                  -

                  - - Statements: 100% (89 / 89)      - - - Branches: 100% (76 / 76)      - - - Functions: 100% (15 / 15)      - - - Lines: 100% (82 / 82)      - - Ignored: none      -

                  -
                  All files » vinyl/
                  -
                  -
                  -
                  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  FileStatementsBranchesFunctionsLines
                  index.js100%(89 / 89)100%(76 / 76)100%(15 / 15)100%(82 / 82)
                  -
                  -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html deleted file mode 100644 index 36a4d769..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/index.js.html +++ /dev/null @@ -1,847 +0,0 @@ - - - - Code coverage report for vinyl/index.js - - - - - - - -
                  -

                  Code coverage report for vinyl/index.js

                  -

                  - - Statements: 100% (89 / 89)      - - - Branches: 100% (76 / 76)      - - - Functions: 100% (15 / 15)      - - - Lines: 100% (82 / 82)      - - Ignored: none      -

                  -
                  All files » vinyl/ » index.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -1761 -1 -1 -1 -1 -1 -1 -1 -1 -  -1 -73 -  -  -73 -73 -  -  -73 -73 -  -  -  -73 -  -  -73 -  -  -1 -26 -  -  -1 -29 -  -  -1 -6 -  -  -  -1 -3 -  -  -1 -14 -2 -  -  -  -12 -7 -  -  -  -  -5 -5 -  -  -  -14 -14 -1 -1 -13 -6 -  -  -14 -  -  -  -  -  -  -  -  -14 -  -75 -  -  -70 -  -5 -  -14 -  -  -1 -6 -6 -  -6 -2 -  -4 -2 -1 -  -1 -  -2 -  -  -  -2 -2 -  -  -1 -6 -  -  -6 -  -6 -4 -  -  -6 -3 -  -  -6 -1 -  -  -6 -  -  -  -  -1 -  -99 -  -  -78 -1 -  -77 -  -  -  -  -1 -  -7 -6 -5 -  -  -1 -  -  -  -1 -  -46 -  -  -9 -  -  -8 -5 -  -  -  -  -1 - 
                  var path = require('path');
                  -var clone = require('lodash').clone;
                  -var cloneStats = require('clone-stats');
                  -var cloneBuffer = require('./lib/cloneBuffer');
                  -var isBuffer = require('./lib/isBuffer');
                  -var isStream = require('./lib/isStream');
                  -var isNull = require('./lib/isNull');
                  -var inspectStream = require('./lib/inspectStream');
                  -var Stream = require('stream');
                  - 
                  -function File(file) {
                  -  if (!file) file = {};
                  - 
                  -  // record path change
                  -  var history = file.path ? [file.path] : file.history;
                  -  this.history = history || [];
                  - 
                  -  // TODO: should this be moved to vinyl-fs?
                  -  this.cwd = file.cwd || process.cwd();
                  -  this.base = file.base || this.cwd;
                  - 
                  -  // stat = fs stats object
                  -  // TODO: should this be moved to vinyl-fs?
                  -  this.stat = file.stat || null;
                  - 
                  -  // contents = stream, buffer, or null if not read
                  -  this.contents = file.contents || null;
                  -}
                  - 
                  -File.prototype.isBuffer = function() {
                  -  return isBuffer(this.contents);
                  -};
                  - 
                  -File.prototype.isStream = function() {
                  -  return isStream(this.contents);
                  -};
                  - 
                  -File.prototype.isNull = function() {
                  -  return isNull(this.contents);
                  -};
                  - 
                  -// TODO: should this be moved to vinyl-fs?
                  -File.prototype.isDirectory = function() {
                  -  return this.isNull() && this.stat && this.stat.isDirectory();
                  -};
                  - 
                  -File.prototype.clone = function(opt) {
                  -  if (typeof opt === 'boolean') {
                  -    opt = {
                  -      deep: opt,
                  -      contents: true
                  -    };
                  -  } else if (!opt) {
                  -    opt = {
                  -      deep: false,
                  -      contents: true
                  -    };
                  -  } else {
                  -    opt.deep = opt.deep === true;
                  -    opt.contents = opt.contents !== false;
                  -  }
                  - 
                  -  // clone our file contents
                  -  var contents;
                  -  if (this.isStream()) {
                  -    contents = this.contents.pipe(new Stream.PassThrough());
                  -    this.contents = this.contents.pipe(new Stream.PassThrough());
                  -  } else if (this.isBuffer()) {
                  -    contents = opt.contents ? cloneBuffer(this.contents) : this.contents;
                  -  }
                  - 
                  -  var file = new File({
                  -    cwd: this.cwd,
                  -    base: this.base,
                  -    stat: (this.stat ? cloneStats(this.stat) : null),
                  -    history: this.history.slice(),
                  -    contents: contents
                  -  });
                  - 
                  -  // clone our custom properties
                  -  Object.keys(this).forEach(function(key) {
                  -    // ignore built-in fields
                  -    if (key === '_contents' || key === 'stat' ||
                  -      key === 'history' || key === 'path' ||
                  -      key === 'base' || key === 'cwd') {
                  -      return;
                  -    }
                  -    file[key] = opt.deep ? clone(this[key], true) : this[key];
                  -  }, this);
                  -  return file;
                  -};
                  - 
                  -File.prototype.pipe = function(stream, opt) {
                  -  if (!opt) opt = {};
                  -  if (typeof opt.end === 'undefined') opt.end = true;
                  - 
                  -  if (this.isStream()) {
                  -    return this.contents.pipe(stream, opt);
                  -  }
                  -  if (this.isBuffer()) {
                  -    if (opt.end) {
                  -      stream.end(this.contents);
                  -    } else {
                  -      stream.write(this.contents);
                  -    }
                  -    return stream;
                  -  }
                  - 
                  -  // isNull
                  -  if (opt.end) stream.end();
                  -  return stream;
                  -};
                  - 
                  -File.prototype.inspect = function() {
                  -  var inspect = [];
                  - 
                  -  // use relative path if possible
                  -  var filePath = (this.base && this.path) ? this.relative : this.path;
                  - 
                  -  if (filePath) {
                  -    inspect.push('"'+filePath+'"');
                  -  }
                  - 
                  -  if (this.isBuffer()) {
                  -    inspect.push(this.contents.inspect());
                  -  }
                  - 
                  -  if (this.isStream()) {
                  -    inspect.push(inspectStream(this.contents));
                  -  }
                  - 
                  -  return '<File '+inspect.join(' ')+'>';
                  -};
                  - 
                  -// virtual attributes
                  -// or stuff with extra logic
                  -Object.defineProperty(File.prototype, 'contents', {
                  -  get: function() {
                  -    return this._contents;
                  -  },
                  -  set: function(val) {
                  -    if (!isBuffer(val) && !isStream(val) && !isNull(val)) {
                  -      throw new Error('File.contents can only be a Buffer, a Stream, or null.');
                  -    }
                  -    this._contents = val;
                  -  }
                  -});
                  - 
                  -// TODO: should this be moved to vinyl-fs?
                  -Object.defineProperty(File.prototype, 'relative', {
                  -  get: function() {
                  -    if (!this.base) throw new Error('No base specified! Can not get relative.');
                  -    if (!this.path) throw new Error('No path specified! Can not get relative.');
                  -    return path.relative(this.base, this.path);
                  -  },
                  -  set: function() {
                  -    throw new Error('File.relative is generated from the base and path attributes. Do not modify it.');
                  -  }
                  -});
                  - 
                  -Object.defineProperty(File.prototype, 'path', {
                  -  get: function() {
                  -    return this.history[this.history.length - 1];
                  -  },
                  -  set: function(path) {
                  -    if (typeof path !== 'string') throw new Error('path should be string');
                  - 
                  -    // record history only when path changed
                  -    if (path && path !== this.path) {
                  -      this.history.push(path);
                  -    }
                  -  }
                  -});
                  - 
                  -module.exports = File;
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html deleted file mode 100644 index 39ec92bc..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/cloneBuffer.js.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - Code coverage report for vinyl/lib/cloneBuffer.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/cloneBuffer.js

                  -

                  - - Statements: 100% (5 / 5)      - - - Branches: 100% (0 / 0)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (5 / 5)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » cloneBuffer.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -7 -81 -  -1 -7 -7 -7 -  - 
                  var Buffer = require('buffer').Buffer;
                  - 
                  -module.exports = function(buf) {
                  -  var out = new Buffer(buf.length);
                  -  buf.copy(out);
                  -  return out;
                  -};
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html deleted file mode 100644 index 5288f5aa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/index.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - Code coverage report for vinyl/lib/ - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/

                  -

                  - - Statements: 100% (22 / 22)      - - - Branches: 100% (8 / 8)      - - - Functions: 100% (5 / 5)      - - - Lines: 100% (20 / 20)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/
                  -
                  -
                  -
                  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                  FileStatementsBranchesFunctionsLines
                  cloneBuffer.js100%(5 / 5)100%(0 / 0)100%(1 / 1)100%(5 / 5)
                  inspectStream.js100%(8 / 8)100%(4 / 4)100%(1 / 1)100%(6 / 6)
                  isBuffer.js100%(4 / 4)100%(2 / 2)100%(1 / 1)100%(4 / 4)
                  isNull.js100%(2 / 2)100%(0 / 0)100%(1 / 1)100%(2 / 2)
                  isStream.js100%(3 / 3)100%(2 / 2)100%(1 / 1)100%(3 / 3)
                  -
                  -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html deleted file mode 100644 index e8e5b360..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/inspectStream.js.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - Code coverage report for vinyl/lib/inspectStream.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/inspectStream.js

                  -

                  - - Statements: 100% (8 / 8)      - - - Branches: 100% (4 / 4)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (6 / 6)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » inspectStream.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -121 -  -1 -9 -  -7 -  -7 -  -7 -  - 
                  var isStream = require('./isStream');
                  - 
                  -module.exports = function(stream) {
                  -  if (!isStream(stream)) return;
                  - 
                  -  var streamType = stream.constructor.name;
                  -  // avoid StreamStream
                  -  if (streamType === 'Stream') streamType = '';
                  - 
                  -  return '<'+streamType+'Stream>';
                  -};
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html deleted file mode 100644 index a44efe47..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isBuffer.js.html +++ /dev/null @@ -1,340 +0,0 @@ - - - - Code coverage report for vinyl/lib/isBuffer.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/isBuffer.js

                  -

                  - - Statements: 100% (4 / 4)      - - - Branches: 100% (2 / 2)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (4 / 4)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » isBuffer.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -5 -6 -71 -1 -  -  -1 -108 - 
                  var buf = require('buffer');
                  -var Buffer = buf.Buffer;
                  - 
                  -// could use Buffer.isBuffer but this is the same exact thing...
                  -module.exports = function(o) {
                  -  return typeof o === 'object' && o instanceof Buffer;
                  -};
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html deleted file mode 100644 index 010d3e00..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isNull.js.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - Code coverage report for vinyl/lib/isNull.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/isNull.js

                  -

                  - - Statements: 100% (2 / 2)      - - - Branches: 100% (0 / 0)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (2 / 2)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » isNull.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -41 -57 -  - 
                  module.exports = function(v) {
                  -  return v === null;
                  -};
                  - 
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html deleted file mode 100644 index 511186fe..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov-report/vinyl/lib/isStream.js.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - Code coverage report for vinyl/lib/isStream.js - - - - - - - -
                  -

                  Code coverage report for vinyl/lib/isStream.js

                  -

                  - - Statements: 100% (3 / 3)      - - - Branches: 100% (2 / 2)      - - - Functions: 100% (1 / 1)      - - - Lines: 100% (3 / 3)      - - Ignored: none      -

                  -
                  All files » vinyl/lib/ » isStream.js
                  -
                  -
                  -
                  
                  -
                  -
                  1 -2 -3 -4 -51 -  -1 -99 - 
                  var Stream = require('stream').Stream;
                  - 
                  -module.exports = function(o) {
                  -  return !!o && o instanceof Stream;
                  -};
                  - -
                  - - - - - - - - diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov.info b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov.info deleted file mode 100644 index bbebe386..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/coverage/lcov.info +++ /dev/null @@ -1,280 +0,0 @@ -TN: -SF:/Users/contra/Projects/vinyl/index.js -FN:11,File -FN:30,(anonymous_2) -FN:34,(anonymous_3) -FN:38,(anonymous_4) -FN:43,(anonymous_5) -FN:47,(anonymous_6) -FN:81,(anonymous_7) -FN:93,(anonymous_8) -FN:114,(anonymous_9) -FN:138,(anonymous_10) -FN:141,(anonymous_11) -FN:151,(anonymous_12) -FN:156,(anonymous_13) -FN:162,(anonymous_14) -FN:165,(anonymous_15) -FNF:15 -FNH:15 -FNDA:73,File -FNDA:26,(anonymous_2) -FNDA:29,(anonymous_3) -FNDA:6,(anonymous_4) -FNDA:3,(anonymous_5) -FNDA:14,(anonymous_6) -FNDA:75,(anonymous_7) -FNDA:6,(anonymous_8) -FNDA:6,(anonymous_9) -FNDA:99,(anonymous_10) -FNDA:78,(anonymous_11) -FNDA:7,(anonymous_12) -FNDA:1,(anonymous_13) -FNDA:46,(anonymous_14) -FNDA:9,(anonymous_15) -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:11,1 -DA:12,73 -DA:15,73 -DA:16,73 -DA:19,73 -DA:20,73 -DA:24,73 -DA:27,73 -DA:30,1 -DA:31,26 -DA:34,1 -DA:35,29 -DA:38,1 -DA:39,6 -DA:43,1 -DA:44,3 -DA:47,1 -DA:48,14 -DA:49,2 -DA:53,12 -DA:54,7 -DA:59,5 -DA:60,5 -DA:64,14 -DA:65,14 -DA:66,1 -DA:67,1 -DA:68,13 -DA:69,6 -DA:72,14 -DA:81,14 -DA:83,75 -DA:86,70 -DA:88,5 -DA:90,14 -DA:93,1 -DA:94,6 -DA:95,6 -DA:97,6 -DA:98,2 -DA:100,4 -DA:101,2 -DA:102,1 -DA:104,1 -DA:106,2 -DA:110,2 -DA:111,2 -DA:114,1 -DA:115,6 -DA:118,6 -DA:120,6 -DA:121,4 -DA:124,6 -DA:125,3 -DA:128,6 -DA:129,1 -DA:132,6 -DA:137,1 -DA:139,99 -DA:142,78 -DA:143,1 -DA:145,77 -DA:150,1 -DA:152,7 -DA:153,6 -DA:154,5 -DA:157,1 -DA:161,1 -DA:163,46 -DA:166,9 -DA:169,8 -DA:170,5 -DA:175,1 -LF:82 -LH:82 -BRDA:12,1,0,14 -BRDA:12,1,1,59 -BRDA:15,2,0,25 -BRDA:15,2,1,48 -BRDA:16,3,0,73 -BRDA:16,3,1,33 -BRDA:19,4,0,73 -BRDA:19,4,1,32 -BRDA:20,5,0,73 -BRDA:20,5,1,39 -BRDA:24,6,0,73 -BRDA:24,6,1,65 -BRDA:27,7,0,73 -BRDA:27,7,1,44 -BRDA:44,8,0,3 -BRDA:44,8,1,1 -BRDA:44,8,2,1 -BRDA:48,9,0,2 -BRDA:48,9,1,12 -BRDA:53,10,0,7 -BRDA:53,10,1,5 -BRDA:65,11,0,1 -BRDA:65,11,1,13 -BRDA:68,12,0,6 -BRDA:68,12,1,7 -BRDA:69,13,0,5 -BRDA:69,13,1,1 -BRDA:75,14,0,2 -BRDA:75,14,1,12 -BRDA:83,15,0,70 -BRDA:83,15,1,5 -BRDA:83,16,0,75 -BRDA:83,16,1,61 -BRDA:83,16,2,47 -BRDA:83,16,3,33 -BRDA:83,16,4,33 -BRDA:83,16,5,19 -BRDA:88,17,0,2 -BRDA:88,17,1,3 -BRDA:94,18,0,3 -BRDA:94,18,1,3 -BRDA:95,19,0,3 -BRDA:95,19,1,3 -BRDA:97,20,0,2 -BRDA:97,20,1,4 -BRDA:100,21,0,2 -BRDA:100,21,1,2 -BRDA:101,22,0,1 -BRDA:101,22,1,1 -BRDA:110,23,0,1 -BRDA:110,23,1,1 -BRDA:118,24,0,3 -BRDA:118,24,1,3 -BRDA:118,25,0,6 -BRDA:118,25,1,5 -BRDA:120,26,0,4 -BRDA:120,26,1,2 -BRDA:124,27,0,3 -BRDA:124,27,1,3 -BRDA:128,28,0,1 -BRDA:128,28,1,5 -BRDA:142,29,0,1 -BRDA:142,29,1,77 -BRDA:142,30,0,78 -BRDA:142,30,1,57 -BRDA:142,30,2,46 -BRDA:152,31,0,1 -BRDA:152,31,1,6 -BRDA:153,32,0,1 -BRDA:153,32,1,5 -BRDA:166,33,0,1 -BRDA:166,33,1,8 -BRDA:169,34,0,5 -BRDA:169,34,1,3 -BRDA:169,35,0,8 -BRDA:169,35,1,7 -BRF:76 -BRH:76 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/cloneBuffer.js -FN:3,(anonymous_1) -FNF:1 -FNH:1 -FNDA:7,(anonymous_1) -DA:1,1 -DA:3,1 -DA:4,7 -DA:5,7 -DA:6,7 -LF:5 -LH:5 -BRF:0 -BRH:0 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/isBuffer.js -FN:5,(anonymous_1) -FNF:1 -FNH:1 -FNDA:108,(anonymous_1) -DA:1,1 -DA:2,1 -DA:5,1 -DA:6,108 -LF:4 -LH:4 -BRDA:6,1,0,108 -BRDA:6,1,1,107 -BRF:2 -BRH:2 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/isStream.js -FN:3,(anonymous_1) -FNF:1 -FNH:1 -FNDA:99,(anonymous_1) -DA:1,1 -DA:3,1 -DA:4,99 -LF:3 -LH:3 -BRDA:4,1,0,99 -BRDA:4,1,1,40 -BRF:2 -BRH:2 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/isNull.js -FN:1,(anonymous_1) -FNF:1 -FNH:1 -FNDA:57,(anonymous_1) -DA:1,1 -DA:2,57 -LF:2 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:/Users/contra/Projects/vinyl/lib/inspectStream.js -FN:3,(anonymous_1) -FNF:1 -FNH:1 -FNDA:9,(anonymous_1) -DA:1,1 -DA:3,1 -DA:4,9 -DA:6,7 -DA:8,7 -DA:10,7 -LF:6 -LH:6 -BRDA:4,1,0,2 -BRDA:4,1,1,7 -BRDA:8,2,0,1 -BRDA:8,2,1,6 -BRF:4 -BRH:4 -end_of_record diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/index.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/index.js deleted file mode 100644 index 09913c3a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/index.js +++ /dev/null @@ -1,175 +0,0 @@ -var path = require('path'); -var clone = require('lodash').clone; -var cloneStats = require('clone-stats'); -var cloneBuffer = require('./lib/cloneBuffer'); -var isBuffer = require('./lib/isBuffer'); -var isStream = require('./lib/isStream'); -var isNull = require('./lib/isNull'); -var inspectStream = require('./lib/inspectStream'); -var Stream = require('stream'); - -function File(file) { - if (!file) file = {}; - - // record path change - var history = file.path ? [file.path] : file.history; - this.history = history || []; - - // TODO: should this be moved to vinyl-fs? - this.cwd = file.cwd || process.cwd(); - this.base = file.base || this.cwd; - - // stat = fs stats object - // TODO: should this be moved to vinyl-fs? - this.stat = file.stat || null; - - // contents = stream, buffer, or null if not read - this.contents = file.contents || null; -} - -File.prototype.isBuffer = function() { - return isBuffer(this.contents); -}; - -File.prototype.isStream = function() { - return isStream(this.contents); -}; - -File.prototype.isNull = function() { - return isNull(this.contents); -}; - -// TODO: should this be moved to vinyl-fs? -File.prototype.isDirectory = function() { - return this.isNull() && this.stat && this.stat.isDirectory(); -}; - -File.prototype.clone = function(opt) { - if (typeof opt === 'boolean') { - opt = { - deep: opt, - contents: true - }; - } else if (!opt) { - opt = { - deep: false, - contents: true - }; - } else { - opt.deep = opt.deep === true; - opt.contents = opt.contents !== false; - } - - // clone our file contents - var contents; - if (this.isStream()) { - contents = this.contents.pipe(new Stream.PassThrough()); - this.contents = this.contents.pipe(new Stream.PassThrough()); - } else if (this.isBuffer()) { - contents = opt.contents ? cloneBuffer(this.contents) : this.contents; - } - - var file = new File({ - cwd: this.cwd, - base: this.base, - stat: (this.stat ? cloneStats(this.stat) : null), - history: this.history.slice(), - contents: contents - }); - - // clone our custom properties - Object.keys(this).forEach(function(key) { - // ignore built-in fields - if (key === '_contents' || key === 'stat' || - key === 'history' || key === 'path' || - key === 'base' || key === 'cwd') { - return; - } - file[key] = opt.deep ? clone(this[key], true) : this[key]; - }, this); - return file; -}; - -File.prototype.pipe = function(stream, opt) { - if (!opt) opt = {}; - if (typeof opt.end === 'undefined') opt.end = true; - - if (this.isStream()) { - return this.contents.pipe(stream, opt); - } - if (this.isBuffer()) { - if (opt.end) { - stream.end(this.contents); - } else { - stream.write(this.contents); - } - return stream; - } - - // isNull - if (opt.end) stream.end(); - return stream; -}; - -File.prototype.inspect = function() { - var inspect = []; - - // use relative path if possible - var filePath = (this.base && this.path) ? this.relative : this.path; - - if (filePath) { - inspect.push('"'+filePath+'"'); - } - - if (this.isBuffer()) { - inspect.push(this.contents.inspect()); - } - - if (this.isStream()) { - inspect.push(inspectStream(this.contents)); - } - - return ''; -}; - -// virtual attributes -// or stuff with extra logic -Object.defineProperty(File.prototype, 'contents', { - get: function() { - return this._contents; - }, - set: function(val) { - if (!isBuffer(val) && !isStream(val) && !isNull(val)) { - throw new Error('File.contents can only be a Buffer, a Stream, or null.'); - } - this._contents = val; - } -}); - -// TODO: should this be moved to vinyl-fs? -Object.defineProperty(File.prototype, 'relative', { - get: function() { - if (!this.base) throw new Error('No base specified! Can not get relative.'); - if (!this.path) throw new Error('No path specified! Can not get relative.'); - return path.relative(this.base, this.path); - }, - set: function() { - throw new Error('File.relative is generated from the base and path attributes. Do not modify it.'); - } -}); - -Object.defineProperty(File.prototype, 'path', { - get: function() { - return this.history[this.history.length - 1]; - }, - set: function(path) { - if (typeof path !== 'string') throw new Error('path should be string'); - - // record history only when path changed - if (path && path !== this.path) { - this.history.push(path); - } - } -}); - -module.exports = File; diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/cloneBuffer.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/cloneBuffer.js deleted file mode 100644 index 89f09eda..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/cloneBuffer.js +++ /dev/null @@ -1,7 +0,0 @@ -var Buffer = require('buffer').Buffer; - -module.exports = function(buf) { - var out = new Buffer(buf.length); - buf.copy(out); - return out; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/inspectStream.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/inspectStream.js deleted file mode 100644 index d36df6ff..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/inspectStream.js +++ /dev/null @@ -1,11 +0,0 @@ -var isStream = require('./isStream'); - -module.exports = function(stream) { - if (!isStream(stream)) return; - - var streamType = stream.constructor.name; - // avoid StreamStream - if (streamType === 'Stream') streamType = ''; - - return '<'+streamType+'Stream>'; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isBuffer.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isBuffer.js deleted file mode 100644 index 0e23782c..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isBuffer.js +++ /dev/null @@ -1,7 +0,0 @@ -var buf = require('buffer'); -var Buffer = buf.Buffer; - -// could use Buffer.isBuffer but this is the same exact thing... -module.exports = function(o) { - return typeof o === 'object' && o instanceof Buffer; -}; \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isNull.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isNull.js deleted file mode 100644 index 7f22c63a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isNull.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function(v) { - return v === null; -}; diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isStream.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isStream.js deleted file mode 100644 index 9ce0929b..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/lib/isStream.js +++ /dev/null @@ -1,5 +0,0 @@ -var Stream = require('stream').Stream; - -module.exports = function(o) { - return !!o && o instanceof Stream; -}; \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/LICENSE.md b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/LICENSE.md deleted file mode 100644 index 146cb32a..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -## The MIT License (MIT) ## - -Copyright (c) 2014 Hugh Kennedy - -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/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/README.md b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/README.md deleted file mode 100644 index 8b12b6fa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# clone-stats [![Flattr this!](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=hughskennedy&url=http://github.com/hughsk/clone-stats&title=clone-stats&description=hughsk/clone-stats%20on%20GitHub&language=en_GB&tags=flattr,github,javascript&category=software)[![experimental](http://hughsk.github.io/stability-badges/dist/experimental.svg)](http://github.com/hughsk/stability-badges) # - -Safely clone node's -[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) instances without -losing their class methods, i.e. `stat.isDirectory()` and co. - -## Usage ## - -[![clone-stats](https://nodei.co/npm/clone-stats.png?mini=true)](https://nodei.co/npm/clone-stats) - -### `copy = require('clone-stats')(stat)` ### - -Returns a clone of the original `fs.Stats` instance (`stat`). - -## License ## - -MIT. See [LICENSE.md](http://github.com/hughsk/clone-stats/blob/master/LICENSE.md) for details. diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/index.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/index.js deleted file mode 100644 index e797cfe6..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/index.js +++ /dev/null @@ -1,13 +0,0 @@ -var Stat = require('fs').Stats - -module.exports = cloneStats - -function cloneStats(stats) { - var replacement = new Stat - - Object.keys(stats).forEach(function(key) { - replacement[key] = stats[key] - }) - - return replacement -} diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/package.json b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/package.json deleted file mode 100644 index e6911657..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "clone-stats", - "description": "Safely clone node's fs.Stats instances without losing their class methods", - "version": "0.0.1", - "main": "index.js", - "browser": "index.js", - "dependencies": {}, - "devDependencies": { - "tape": "~2.3.2" - }, - "scripts": { - "test": "node test" - }, - "author": { - "name": "Hugh Kennedy", - "email": "hughskennedy@gmail.com", - "url": "http://hughsk.io/" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "git://github.com/hughsk/clone-stats" - }, - "bugs": { - "url": "https://github.com/hughsk/clone-stats/issues" - }, - "homepage": "https://github.com/hughsk/clone-stats", - "keywords": [ - "stats", - "fs", - "clone", - "copy", - "prototype" - ], - "readme": "# clone-stats [![Flattr this!](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=hughskennedy&url=http://github.com/hughsk/clone-stats&title=clone-stats&description=hughsk/clone-stats%20on%20GitHub&language=en_GB&tags=flattr,github,javascript&category=software)[![experimental](http://hughsk.github.io/stability-badges/dist/experimental.svg)](http://github.com/hughsk/stability-badges) #\n\nSafely clone node's\n[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) instances without\nlosing their class methods, i.e. `stat.isDirectory()` and co.\n\n## Usage ##\n\n[![clone-stats](https://nodei.co/npm/clone-stats.png?mini=true)](https://nodei.co/npm/clone-stats)\n\n### `copy = require('clone-stats')(stat)` ###\n\nReturns a clone of the original `fs.Stats` instance (`stat`).\n\n## License ##\n\nMIT. See [LICENSE.md](http://github.com/hughsk/clone-stats/blob/master/LICENSE.md) for details.\n", - "readmeFilename": "README.md", - "_id": "clone-stats@0.0.1", - "dist": { - "shasum": "b88f94a82cf38b8791d58046ea4029ad88ca99d1", - "tarball": "http://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" - }, - "_from": "clone-stats@^0.0.1", - "_npmVersion": "1.3.22", - "_npmUser": { - "name": "hughsk", - "email": "hughskennedy@gmail.com" - }, - "maintainers": [ - { - "name": "hughsk", - "email": "hughskennedy@gmail.com" - } - ], - "directories": {}, - "_shasum": "b88f94a82cf38b8791d58046ea4029ad88ca99d1", - "_resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/test.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/test.js deleted file mode 100644 index e4bb2814..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/node_modules/clone-stats/test.js +++ /dev/null @@ -1,36 +0,0 @@ -var test = require('tape') -var clone = require('./') -var fs = require('fs') - -test('file', function(t) { - compare(t, fs.statSync(__filename)) - t.end() -}) - -test('directory', function(t) { - compare(t, fs.statSync(__dirname)) - t.end() -}) - -function compare(t, stat) { - var copy = clone(stat) - - t.deepEqual(stat, copy, 'clone has equal properties') - t.ok(stat instanceof fs.Stats, 'original is an fs.Stat') - t.ok(copy instanceof fs.Stats, 'copy is an fs.Stat') - - ;['isDirectory' - , 'isFile' - , 'isBlockDevice' - , 'isCharacterDevice' - , 'isSymbolicLink' - , 'isFIFO' - , 'isSocket' - ].forEach(function(method) { - t.equal( - stat[method].call(stat) - , copy[method].call(copy) - , 'equal value for stat.' + method + '()' - ) - }) -} diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/package.json b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/package.json deleted file mode 100644 index 29020314..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "vinyl", - "description": "A virtual file format", - "version": "0.4.3", - "homepage": "http://github.com/wearefractal/vinyl", - "repository": { - "type": "git", - "url": "git://github.com/wearefractal/vinyl.git" - }, - "author": { - "name": "Fractal", - "email": "contact@wearefractal.com", - "url": "http://wearefractal.com/" - }, - "main": "./index.js", - "dependencies": { - "clone-stats": "^0.0.1", - "lodash": "^2.4.1" - }, - "devDependencies": { - "mocha": "^1.17.0", - "should": "^4.0.4", - "mocha-lcov-reporter": "^0.0.1", - "coveralls": "^2.6.1", - "istanbul": "^0.3.0", - "rimraf": "^2.2.5", - "jshint": "^2.4.1", - "buffer-equal": "0.0.1", - "lodash.templatesettings": "^2.4.1", - "event-stream": "^3.1.0" - }, - "scripts": { - "test": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter spec && jshint .", - "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" - }, - "engines": { - "node": ">= 0.9" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/wearefractal/vinyl/raw/master/LICENSE" - } - ], - "gitHead": "6eae432519b007c313a8df83b093adfb97a2944c", - "bugs": { - "url": "https://github.com/wearefractal/vinyl/issues" - }, - "_id": "vinyl@0.4.3", - "_shasum": "19f61a1b28e72b4c50697889dbe91d7503943ecf", - "_from": "vinyl@^0.4.0", - "_npmVersion": "1.4.21", - "_npmUser": { - "name": "fractal", - "email": "contact@wearefractal.com" - }, - "maintainers": [ - { - "name": "fractal", - "email": "contact@wearefractal.com" - } - ], - "dist": { - "shasum": "19f61a1b28e72b4c50697889dbe91d7503943ecf", - "tarball": "http://registry.npmjs.org/vinyl/-/vinyl-0.4.3.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.3.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/perf/clone.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/perf/clone.js deleted file mode 100644 index 4df85787..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/perf/clone.js +++ /dev/null @@ -1,59 +0,0 @@ -var File = require('../'); - -var contents = new Buffer('blah blah blah'); - -var originalFile = new File({ - path: 'yo.coffee', - contents: contents -}); - -// simulate some history -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; -originalFile.path = 'yo.js'; - -originalFile.ast = { - a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { -a: { - b: { - c: { - - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } -}; - -for (var i = 0; i < 10000; i++) { - originalFile.clone(true).ast; -} \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/File.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/File.js deleted file mode 100644 index 419e7aac..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/File.js +++ /dev/null @@ -1,753 +0,0 @@ -var Stream = require('stream'); -var fs = require('fs'); -var path = require('path'); -var es = require('event-stream'); -var File = require('../'); - -var should = require('should'); -require('mocha'); - -describe('File', function() { - describe('constructor()', function() { - it('should default cwd to process.cwd', function(done) { - var file = new File(); - file.cwd.should.equal(process.cwd()); - done(); - }); - - it('should default base to cwd', function(done) { - var cwd = '/'; - var file = new File({cwd: cwd}); - file.base.should.equal(cwd); - done(); - }); - - it('should default base to cwd even when none is given', function(done) { - var file = new File(); - file.base.should.equal(process.cwd()); - done(); - }); - - it('should default path to null', function(done) { - var file = new File(); - should.not.exist(file.path); - done(); - }); - - it('should default history to []', function(done) { - var file = new File(); - file.history.should.eql([]); - done(); - }); - - it('should default stat to null', function(done) { - var file = new File(); - should.not.exist(file.stat); - done(); - }); - - it('should default contents to null', function(done) { - var file = new File(); - should.not.exist(file.contents); - done(); - }); - - it('should set base to given value', function(done) { - var val = '/'; - var file = new File({base: val}); - file.base.should.equal(val); - done(); - }); - - it('should set cwd to given value', function(done) { - var val = '/'; - var file = new File({cwd: val}); - file.cwd.should.equal(val); - done(); - }); - - it('should set path to given value', function(done) { - var val = '/test.coffee'; - var file = new File({path: val}); - file.path.should.equal(val); - file.history.should.eql([val]); - done(); - }); - - it('should set history to given value', function(done) { - var val = '/test.coffee'; - var file = new File({history: [val]}); - file.path.should.equal(val); - file.history.should.eql([val]); - done(); - }); - - it('should set stat to given value', function(done) { - var val = {}; - var file = new File({stat: val}); - file.stat.should.equal(val); - done(); - }); - - it('should set contents to given value', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.contents.should.equal(val); - done(); - }); - }); - - describe('isBuffer()', function() { - it('should return true when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.isBuffer().should.equal(true); - done(); - }); - - it('should return false when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val}); - file.isBuffer().should.equal(false); - done(); - }); - - it('should return false when the contents are a null', function(done) { - var file = new File({contents: null}); - file.isBuffer().should.equal(false); - done(); - }); - }); - - describe('isStream()', function() { - it('should return false when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.isStream().should.equal(false); - done(); - }); - - it('should return true when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val}); - file.isStream().should.equal(true); - done(); - }); - - it('should return false when the contents are a null', function(done) { - var file = new File({contents: null}); - file.isStream().should.equal(false); - done(); - }); - }); - - describe('isNull()', function() { - it('should return false when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val}); - file.isNull().should.equal(false); - done(); - }); - - it('should return false when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val}); - file.isNull().should.equal(false); - done(); - }); - - it('should return true when the contents are a null', function(done) { - var file = new File({contents: null}); - file.isNull().should.equal(true); - done(); - }); - }); - - describe('isDirectory()', function() { - var fakeStat = { - isDirectory: function() { - return true; - } - }; - - it('should return false when the contents are a Buffer', function(done) { - var val = new Buffer('test'); - var file = new File({contents: val, stat: fakeStat}); - file.isDirectory().should.equal(false); - done(); - }); - - it('should return false when the contents are a Stream', function(done) { - var val = new Stream(); - var file = new File({contents: val, stat: fakeStat}); - file.isDirectory().should.equal(false); - done(); - }); - - it('should return true when the contents are a null', function(done) { - var file = new File({contents: null, stat: fakeStat}); - file.isDirectory().should.equal(true); - done(); - }); - }); - - describe('clone()', function() { - it('should copy all attributes over with Buffer', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Buffer('test') - }; - var file = new File(options); - var file2 = file.clone(); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - file2.contents.should.not.equal(file.contents, 'buffer ref should be different'); - file2.contents.toString('utf8').should.equal(file.contents.toString('utf8')); - done(); - }); - - it('should copy buffer\'s reference with option contents: false', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.js', - contents: new Buffer('test') - }; - - var file = new File(options); - - var copy1 = file.clone({ contents: false }); - copy1.contents.should.equal(file.contents); - - var copy2 = file.clone({}); - copy2.contents.should.not.equal(file.contents); - - var copy3 = file.clone({ contents: 'any string' }); - copy3.contents.should.not.equal(file.contents); - - done(); - }); - - it('should copy all attributes over with Stream', function(done) { - var contents = new Stream.PassThrough(); - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: contents - }; - var file = new File(options); - var file2 = file.clone(); - - contents.write(new Buffer('wa')); - - process.nextTick(function() { - contents.write(new Buffer('dup')); - contents.end(); - }); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - file2.contents.should.not.equal(file.contents, 'stream ref should not be the same'); - file.contents.pipe(es.wait(function(err, data) { - file2.contents.pipe(es.wait(function(err, data2) { - data2.should.not.equal(data, 'stream contents ref should not be the same'); - data2.should.eql(data, 'stream contents should be the same'); - })); - })); - done(); - }); - - it('should copy all attributes over with null', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - var file = new File(options); - var file2 = file.clone(); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - should.not.exist(file2.contents); - done(); - }); - - it('should properly clone the `stat` property', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.js', - contents: new Buffer('test'), - stat: fs.statSync(__filename) - }; - - var file = new File(options); - var copy = file.clone(); - - copy.stat.isFile().should.equal(true); - copy.stat.isDirectory().should.equal(false); - should(file.stat instanceof fs.Stats).equal(true); - should(copy.stat instanceof fs.Stats).equal(true); - - done(); - }); - - it('should properly clone the `history` property', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.js', - contents: new Buffer('test'), - stat: fs.statSync(__filename) - }; - - var file = new File(options); - var copy = file.clone(); - - copy.history[0].should.equal(options.path); - copy.path = 'lol'; - file.path.should.not.equal(copy.path); - done(); - }); - - it('should copy custom properties', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - - var file = new File(options); - file.custom = { a: 'custom property' }; - - var file2 = file.clone(); - - file2.should.not.equal(file, 'refs should be different'); - file2.cwd.should.equal(file.cwd); - file2.base.should.equal(file.base); - file2.path.should.equal(file.path); - file2.custom.should.equal(file.custom); - file2.custom.a.should.equal(file.custom.a); - - done(); - }); - - it('should copy history', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - - var file = new File(options); - file.path = '/test/test.js'; - file.path = '/test/test-938di2s.js'; - var file2 = file.clone(); - - file2.history.should.eql([ - '/test/test.coffee', - '/test/test.js', - '/test/test-938di2s.js' - ]); - file2.history.should.not.equal([ - '/test/test.coffee', - '/test/test.js', - '/test/test-938di2s.js' - ]); - file2.path.should.eql('/test/test-938di2s.js'); - - done(); - }); - - it('should copy all attributes deeply', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - - var file = new File(options); - file.custom = { a: 'custom property' }; - - var file2 = file.clone(true); - file2.custom.should.eql(file.custom); - file2.custom.should.not.equal(file.custom); - file2.custom.a.should.equal(file.custom.a); - - var file3 = file.clone({ deep: true }); - file3.custom.should.eql(file.custom); - file3.custom.should.not.equal(file.custom); - file3.custom.a.should.equal(file.custom.a); - - var file4 = file.clone(false); - file4.custom.should.eql(file.custom); - file4.custom.should.equal(file.custom); - file4.custom.a.should.equal(file.custom.a); - - var file5 = file.clone({ deep: false }); - file5.custom.should.eql(file.custom); - file5.custom.should.equal(file.custom); - file5.custom.a.should.equal(file.custom.a); - - done(); - }); - }); - - describe('pipe()', function() { - it('should write to stream with Buffer', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Buffer('test') - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(options.contents.toString('utf8')); - }); - stream.on('end', function() { - done(); - }); - var ret = file.pipe(stream); - ret.should.equal(stream, 'should return the stream'); - }); - - it('should pipe to stream with Stream', function(done) { - var testChunk = new Buffer('test'); - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Stream.PassThrough() - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(testChunk.toString('utf8')); - done(); - }); - var ret = file.pipe(stream); - ret.should.equal(stream, 'should return the stream'); - - file.contents.write(testChunk); - }); - - it('should do nothing with null', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function() { - throw new Error('should not write'); - }); - stream.on('end', function() { - done(); - }); - var ret = file.pipe(stream); - ret.should.equal(stream, 'should return the stream'); - }); - - it('should write to stream with Buffer', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Buffer('test') - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(options.contents.toString('utf8')); - done(); - }); - stream.on('end', function() { - throw new Error('should not end'); - }); - var ret = file.pipe(stream, {end: false}); - ret.should.equal(stream, 'should return the stream'); - }); - - it('should pipe to stream with Stream', function(done) { - var testChunk = new Buffer('test'); - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Stream.PassThrough() - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function(chunk) { - should.exist(chunk); - (chunk instanceof Buffer).should.equal(true, 'should write as a buffer'); - chunk.toString('utf8').should.equal(testChunk.toString('utf8')); - done(); - }); - stream.on('end', function() { - throw new Error('should not end'); - }); - var ret = file.pipe(stream, {end: false}); - ret.should.equal(stream, 'should return the stream'); - - file.contents.write(testChunk); - }); - - it('should do nothing with null', function(done) { - var options = { - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }; - var file = new File(options); - var stream = new Stream.PassThrough(); - stream.on('data', function() { - throw new Error('should not write'); - }); - stream.on('end', function() { - throw new Error('should not end'); - }); - var ret = file.pipe(stream, {end: false}); - ret.should.equal(stream, 'should return the stream'); - process.nextTick(done); - }); - }); - - describe('inspect()', function() { - it('should return correct format when no contents and no path', function(done) { - var file = new File(); - file.inspect().should.equal(''); - done(); - }); - - it('should return correct format when Buffer and no path', function(done) { - var val = new Buffer('test'); - var file = new File({ - contents: val - }); - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when Buffer and relative path', function(done) { - var val = new Buffer('test'); - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: val - }); - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when Buffer and only path and no base', function(done) { - var val = new Buffer('test'); - var file = new File({ - cwd: '/', - path: '/test/test.coffee', - contents: val - }); - delete file.base; - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when Stream and relative path', function(done) { - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: new Stream.PassThrough() - }); - file.inspect().should.equal('>'); - done(); - }); - - it('should return correct format when null and relative path', function(done) { - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee', - contents: null - }); - file.inspect().should.equal(''); - done(); - }); - }); - - describe('contents get/set', function() { - it('should work with Buffer', function(done) { - var val = new Buffer('test'); - var file = new File(); - file.contents = val; - file.contents.should.equal(val); - done(); - }); - - it('should work with Stream', function(done) { - var val = new Stream.PassThrough(); - var file = new File(); - file.contents = val; - file.contents.should.equal(val); - done(); - }); - - it('should work with null', function(done) { - var val = null; - var file = new File(); - file.contents = val; - (file.contents === null).should.equal(true); - done(); - }); - - it('should not work with string', function(done) { - var val = 'test'; - var file = new File(); - try { - file.contents = val; - } catch (err) { - should.exist(err); - done(); - } - }); - }); - - describe('relative get/set', function() { - it('should error on set', function(done) { - var file = new File(); - try { - file.relative = 'test'; - } catch (err) { - should.exist(err); - done(); - } - }); - - it('should error on get when no base', function(done) { - var a; - var file = new File(); - delete file.base; - try { - a = file.relative; - } catch (err) { - should.exist(err); - done(); - } - }); - - it('should error on get when no path', function(done) { - var a; - var file = new File(); - try { - a = file.relative; - } catch (err) { - should.exist(err); - done(); - } - }); - - it('should return a relative path from base', function(done) { - var file = new File({ - cwd: '/', - base: '/test/', - path: '/test/test.coffee' - }); - file.relative.should.equal('test.coffee'); - done(); - }); - - it('should return a relative path from cwd', function(done) { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - file.relative.should.equal(path.join('test','test.coffee')); - done(); - }); - }); - - describe('path get/set', function() { - - it('should record history when instantiation', function() { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee']); - }); - - it('should record history when path change', function() { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - - file.path = '/test/test.js'; - file.path.should.eql('/test/test.js'); - file.history.should.eql(['/test/test.coffee', '/test/test.js']); - - file.path = '/test/test.coffee'; - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee', '/test/test.js', '/test/test.coffee']); - }); - - it('should not record history when set the same path', function() { - var file = new File({ - cwd: '/', - path: '/test/test.coffee' - }); - - file.path = '/test/test.coffee'; - file.path = '/test/test.coffee'; - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee']); - - // ignore when set empty string - file.path = ''; - file.path.should.eql('/test/test.coffee'); - file.history.should.eql(['/test/test.coffee']); - }); - - it('should throw when set path null', function() { - var file = new File({ - cwd: '/', - path: null - }); - - should.not.exist(file.path); - file.history.should.eql([]); - - (function() { - file.path = null; - }).should.throw('path should be string'); - }); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/cloneBuffer.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/cloneBuffer.js deleted file mode 100644 index 34b3e7c1..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/cloneBuffer.js +++ /dev/null @@ -1,27 +0,0 @@ -var cloneBuffer = require('../lib/cloneBuffer'); -var should = require('should'); -require('mocha'); - -describe('cloneBuffer()', function() { - it('should return a new Buffer reference', function(done) { - var testBuffer = new Buffer('test'); - var testBuffer2 = cloneBuffer(testBuffer); - - should.exist(testBuffer2, 'should return something'); - (testBuffer2 instanceof Buffer).should.equal(true, 'should return a Buffer'); - testBuffer2.should.not.equal(testBuffer, 'pointer should change'); - done(); - }); - - it('should not replicate modifications to the original buffer', function(done) { - var testBuffer = new Buffer('test'); - var testBuffer2 = cloneBuffer(testBuffer); - - // test that changes dont modify both pointers - testBuffer2.write('w'); - - testBuffer.toString('utf8').should.equal('test', 'original should stay the same'); - testBuffer2.toString('utf8').should.equal('west', 'new buffer should be modified'); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/inspectStream.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/inspectStream.js deleted file mode 100644 index fe1802c5..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/inspectStream.js +++ /dev/null @@ -1,53 +0,0 @@ -var inspectStream = require('../lib/inspectStream'); -var Stream = require('stream'); -var should = require('should'); -require('mocha'); - -describe('inspectStream()', function() { - it('should work on a core Stream', function(done) { - var testStream = new Stream(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Readable Stream', function(done) { - var testStream = new Stream.Readable(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Writable Stream', function(done) { - var testStream = new Stream.Writable(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Duplex Stream', function(done) { - var testStream = new Stream.Duplex(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core Transform Stream', function(done) { - var testStream = new Stream.Transform(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should work on a core PassThrough Stream', function(done) { - var testStream = new Stream.PassThrough(); - inspectStream(testStream).should.equal(''); - done(); - }); - - it('should not work on a Buffer', function(done) { - var testBuffer = new Buffer('test'); - should.not.exist(inspectStream(testBuffer)); - done(); - }); - - it('should not work on a null', function(done) { - should.not.exist(inspectStream(null)); - done(); - }); -}); \ No newline at end of file diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isBuffer.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isBuffer.js deleted file mode 100644 index 432ad2aa..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isBuffer.js +++ /dev/null @@ -1,29 +0,0 @@ -var isBuffer = require('../lib/isBuffer'); -var Stream = require('stream'); -require('should'); -require('mocha'); - -describe('isBuffer()', function() { - it('should return true on a Buffer', function(done) { - var testBuffer = new Buffer('test'); - isBuffer(testBuffer).should.equal(true); - done(); - }); - - it('should return false on a Stream', function(done) { - var testStream = new Stream(); - isBuffer(testStream).should.equal(false); - done(); - }); - - it('should return false on a null', function(done) { - isBuffer(null).should.equal(false); - done(); - }); - - it('should return false on a array of numbers', function(done) { - var testArray = [1, 2, 3]; - isBuffer(testArray).should.equal(false); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isNull.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isNull.js deleted file mode 100644 index 356934a6..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isNull.js +++ /dev/null @@ -1,22 +0,0 @@ -var isNull = require('../lib/isNull'); -require('should'); -require('mocha'); - -describe('isNull()', function() { - it('should return true on null', function(done) { - isNull(null).should.equal(true); - done(); - }); - - it('should return false on undefined', function(done) { - isNull().should.equal(false); - isNull(undefined).should.equal(false); - done(); - }); - - it('should return false on defined values', function(done) { - isNull(1).should.equal(false); - isNull('test').should.equal(false); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isStream.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isStream.js deleted file mode 100644 index 5cc0e0b1..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/node_modules/vinyl/test/isStream.js +++ /dev/null @@ -1,29 +0,0 @@ -var isStream = require('../lib/isStream'); -var Stream = require('stream'); -require('should'); -require('mocha'); - -describe('isStream()', function() { - it('should return true on a Stream', function(done) { - var testStream = new Stream(); - isStream(testStream).should.equal(true); - done(); - }); - - it('should return false on a Buffer', function(done) { - var testBuffer = new Buffer('test'); - isStream(testBuffer).should.equal(false); - done(); - }); - - it('should return false on a null', function(done) { - isStream(null).should.equal(false); - done(); - }); - - it('should return false on a array of numbers', function(done) { - var testArray = [1, 2, 3]; - isStream(testArray).should.equal(false); - done(); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/package.json b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/package.json deleted file mode 100644 index 75f37d23..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "vinyl-fs", - "description": "Vinyl adapter for the file system", - "version": "0.3.10", - "homepage": "http://github.com/wearefractal/vinyl-fs", - "repository": { - "type": "git", - "url": "git://github.com/wearefractal/vinyl-fs.git" - }, - "author": { - "name": "Fractal", - "email": "contact@wearefractal.com", - "url": "http://wearefractal.com/" - }, - "main": "./index.js", - "dependencies": { - "glob-stream": "^3.1.5", - "glob-watcher": "^0.0.6", - "graceful-fs": "^3.0.0", - "lodash": "^2.4.1", - "mkdirp": "^0.5.0", - "strip-bom": "^1.0.0", - "through2": "^0.6.1", - "vinyl": "^0.4.0" - }, - "devDependencies": { - "buffer-equal": "^0.0.1", - "coveralls": "^2.6.1", - "istanbul": "^0.3.0", - "jshint": "^2.4.1", - "mocha": "^2.0.0", - "mocha-lcov-reporter": "^0.0.1", - "rimraf": "^2.2.5", - "should": "^4.0.0", - "sinon": "^1.10.3" - }, - "scripts": { - "test": "mocha --reporter spec && jshint lib", - "coveralls": "istanbul cover _mocha -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" - }, - "engines": { - "node": ">= 0.10" - }, - "engineStrict": true, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/wearefractal/vinyl-fs/raw/master/LICENSE" - } - ], - "gitHead": "c6e7433a93d052905611680dc3f6f87c8e629376", - "bugs": { - "url": "https://github.com/wearefractal/vinyl-fs/issues" - }, - "_id": "vinyl-fs@0.3.10", - "_shasum": "f59ac977cb040e95df865ad34cdeb00f57f31f47", - "_from": "vinyl-fs@^0.3.0", - "_npmVersion": "2.1.4", - "_nodeVersion": "0.10.32", - "_npmUser": { - "name": "fractal", - "email": "contact@wearefractal.com" - }, - "maintainers": [ - { - "name": "fractal", - "email": "contact@wearefractal.com" - } - ], - "dist": { - "shasum": "f59ac977cb040e95df865ad34cdeb00f57f31f47", - "tarball": "http://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.10.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.10.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/dest.js b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/dest.js deleted file mode 100644 index 7704f8de..00000000 --- a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/dest.js +++ /dev/null @@ -1,631 +0,0 @@ -var spies = require('./spy'); -var chmodSpy = spies.chmodSpy; -var statSpy = spies.statSpy; - -var vfs = require('../'); - -var path = require('path'); -var fs = require('graceful-fs'); -var rimraf = require('rimraf'); - -var bufEqual = require('buffer-equal'); -var through = require('through2'); -var File = require('vinyl'); - -var should = require('should'); -require('mocha'); - -var wipeOut = function(cb) { - rimraf(path.join(__dirname, './out-fixtures/'), cb); - spies.setError('false'); - statSpy.reset(); - chmodSpy.reset(); -}; - -var dataWrap = function(fn) { - return function(data, enc, cb) { - fn(data); - cb(); - }; -}; - -var realMode = function(n) { - return n & 07777; -}; - -describe('dest stream', function() { - beforeEach(wipeOut); - afterEach(wipeOut); - - it('should explode on invalid folder', function(done) { - var stream; - try { - stream = gulp.dest(); - } catch (err) { - should.exist(err); - should.not.exist(stream); - done(); - } - }); - - it('should pass through writes with cwd', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - - var expectedFile = new File({ - base: __dirname, - cwd: __dirname, - path: inputPath, - contents: null - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - done(); - }; - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should pass through writes with default cwd', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - - var expectedFile = new File({ - base: __dirname, - cwd: __dirname, - path: inputPath, - contents: null - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - done(); - }; - - var stream = vfs.dest(path.join(__dirname, './out-fixtures/')); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should not write null files', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: null - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - fs.existsSync(expectedPath).should.equal(false); - done(); - }; - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should write buffer files to the right folder with relative cwd', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedContents = fs.readFileSync(inputPath); - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - fs.existsSync(expectedPath).should.equal(true); - bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true); - done(); - }; - - var stream = vfs.dest('./out-fixtures/', {cwd: path.relative(process.cwd(), __dirname)}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should write buffer files to the right folder with function and relative cwd', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedContents = fs.readFileSync(inputPath); - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - fs.existsSync(expectedPath).should.equal(true); - bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true); - done(); - }; - - var stream = vfs.dest(function(file){ - should.exist(file); - file.should.equal(expectedFile); - return './out-fixtures'; - }, {cwd: path.relative(process.cwd(), __dirname)}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should write buffer files to the right folder', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0655; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents, - stat: { - mode: expectedMode - } - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - fs.existsSync(expectedPath).should.equal(true); - bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true); - realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode); - done(); - }; - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should write streaming files to the right folder', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0655; - - var contentStream = through.obj(); - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: contentStream, - stat: { - mode: expectedMode - } - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - fs.existsSync(expectedPath).should.equal(true); - bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true); - realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode); - done(); - }; - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - setTimeout(function(){ - contentStream.write(expectedContents); - contentStream.end(); - }, 100); - stream.end(); - }); - - it('should write directories to the right folder', function(done) { - var inputPath = path.join(__dirname, './fixtures/test'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test'); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0655; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: null, - stat: { - isDirectory: function(){ - return true; - }, - mode: expectedMode - } - }); - - var onEnd = function(){ - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - fs.existsSync(expectedPath).should.equal(true); - fs.lstatSync(expectedPath).isDirectory().should.equal(true); - realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode); - done(); - }; - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should allow piping multiple dests in streaming mode', function(done) { - var inputPath1 = path.join(__dirname, './out-fixtures/multiple-first'); - var inputPath2 = path.join(__dirname, './out-fixtures/multiple-second'); - var inputBase = path.join(__dirname, './out-fixtures/'); - var srcPath = path.join(__dirname, './fixtures/test.coffee'); - var stream1 = vfs.dest('./out-fixtures/', {cwd: __dirname}); - var stream2 = vfs.dest('./out-fixtures/', {cwd: __dirname}); - var content = fs.readFileSync(srcPath); - var rename = through.obj(function(file, _, next) { - file.path = inputPath2; - this.push(file); - next(); - }); - - stream1.on('data', function(file) { - file.path.should.equal(inputPath1); - }) - - stream1.pipe(rename).pipe(stream2); - stream2.on('data', function(file) { - file.path.should.equal(inputPath2); - }).once('end', function() { - fs.readFileSync(inputPath1, 'utf8').should.equal(content.toString()); - fs.readFileSync(inputPath2, 'utf8').should.equal(content.toString()); - done(); - }); - - var file = new File({ - base: inputBase, - path: inputPath1, - cwd: __dirname, - contents: content - }) - - stream1.write(file); - stream1.end(); - }); - - it('should update file mode to match the vinyl mode', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var startMode = 0655; - var expectedMode = 0722; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents, - stat: { - mode: expectedMode - } - }); - - var onEnd = function(){ - should(chmodSpy.called).be.ok; - buffered.length.should.equal(1); - buffered[0].should.equal(expectedFile); - fs.existsSync(expectedPath).should.equal(true); - realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode); - done(); - }; - - fs.mkdirSync(expectedBase); - fs.closeSync(fs.openSync(expectedPath, 'w')); - fs.chmodSync(expectedPath, startMode); - - chmodSpy.reset(); - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - it('should update directory mode to match the vinyl mode', function(done) { - var inputBase = path.join(__dirname, './fixtures/'); - var inputPath = path.join(__dirname, './fixtures/wow'); - var expectedPath = path.join(__dirname, './out-fixtures/wow'); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - - var firstFile = new File({ - base: inputBase, - cwd: __dirname, - path: expectedPath, - stat: fs.statSync(inputPath) - }); - var startMode = firstFile.stat.mode; - var expectedMode = 0727; - - var expectedFile = new File(firstFile); - expectedFile.stat.mode = (startMode & ~07777) | expectedMode; - - var onEnd = function(){ - buffered.length.should.equal(2); - buffered[0].should.equal(firstFile); - buffered[1].should.equal(expectedFile); - buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed'); - buffered[0].base.should.equal(expectedBase, 'base should have changed'); - buffered[0].path.should.equal(expectedPath, 'path should have changed'); - realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode); - done(); - }; - - fs.mkdirSync(expectedBase); - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - - stream.pipe(bufferStream); - stream.write(firstFile); - stream.write(expectedFile); - stream.end(); - }); - - it('should report IO errors', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0722; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents, - stat: { - mode: expectedMode - } - }); - - fs.mkdirSync(expectedBase); - fs.closeSync(fs.openSync(expectedPath, 'w')); - fs.chmodSync(expectedPath, 0); - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - stream.on('error', function(err) { - err.code.should.equal('EACCES'); - done(); - }); - stream.write(expectedFile); - }); - - it('should report stat errors', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0722; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents, - stat: { - mode: expectedMode - } - }); - - fs.mkdirSync(expectedBase); - fs.closeSync(fs.openSync(expectedPath, 'w')); - - spies.setError(function(mod, fn) { - if (fn === 'stat' && arguments[2] === expectedPath) { - return new Error('stat error'); - } - }); - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - stream.on('error', function(err) { - err.message.should.equal('stat error'); - done(); - }); - stream.write(expectedFile); - }); - - it('should report chmod errors', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0722; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents, - stat: { - mode: expectedMode - } - }); - - fs.mkdirSync(expectedBase); - fs.closeSync(fs.openSync(expectedPath, 'w')); - - spies.setError(function(mod, fn) { - if (fn === 'chmod' && arguments[2] === expectedPath) { - return new Error('chmod error'); - } - }); - - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - stream.on('error', function(err) { - err.message.should.equal('chmod error'); - done(); - }); - stream.write(expectedFile); - }); - - it('should not chmod a matching file', function(done) { - var inputPath = path.join(__dirname, './fixtures/test.coffee'); - var inputBase = path.join(__dirname, './fixtures/'); - var expectedPath = path.join(__dirname, './out-fixtures/test.coffee'); - var expectedContents = fs.readFileSync(inputPath); - var expectedCwd = __dirname; - var expectedBase = path.join(__dirname, './out-fixtures'); - var expectedMode = 0722; - - var expectedFile = new File({ - base: inputBase, - cwd: __dirname, - path: inputPath, - contents: expectedContents, - stat: { - mode: expectedMode - } - }); - - var expectedCount = 0; - spies.setError(function(mod, fn) { - if (fn === 'stat' && arguments[2] === expectedPath) { - expectedCount++; - } - }); - - var onEnd = function(){ - expectedCount.should.equal(1); - should(chmodSpy.called).be.not.ok; - realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode); - done(); - }; - - fs.mkdirSync(expectedBase); - fs.closeSync(fs.openSync(expectedPath, 'w')); - fs.chmodSync(expectedPath, expectedMode); - - statSpy.reset(); - chmodSpy.reset(); - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - var buffered = []; - bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd); - - stream.pipe(bufferStream); - stream.write(expectedFile); - stream.end(); - }); - - ['end', 'finish'].forEach(function(eventName) { - it('should emit ' + eventName + ' event', function(done) { - var srcPath = path.join(__dirname, './fixtures/test.coffee'); - var stream = vfs.dest('./out-fixtures/', {cwd: __dirname}); - - stream.on(eventName, function() { - done(); - }); - - var file = new File({ - path: srcPath, - cwd: __dirname, - contents: new Buffer("1234567890") - }); - - stream.write(file); - stream.end(); - }); - }); -}); diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf16be.txt b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf16be.txt deleted file mode 100644 index b9dce78a5d31af4803acd1a0f0dfc14f064a5de1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmX|+I}XAy5Jacu26Qf=0Eq@sM*@i=qJaY#5&}waq&RRn3Xa4Tc-{cbe#Sc=zn?E@ zuZymVayru+l}y7P<@I1MK)hWXxZY@{g_hJzYt4Dvs;8dRDlmE2!LB37&GahJPDg5G zyEjIUb8?Hu>i*d9+Q4pAn^J>j{bf4+Qmn{O;+32Wrj#?&PC0#o+uan?UxFJmPf0ua E03tFf0ssI2 diff --git a/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf16le.txt b/spec/fixture/node_modules/gulp/node_modules/vinyl-fs/test/fixtures/bom-utf16le.txt deleted file mode 100644 index 07cc600c98675d221bb56d10af38e650538734c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmX|+%?`mp6otRFH?W%}3lbZ#mXJt@4G%E1O4?47PI);CkK`4cxy9!GoVn*`-p>~Y zuH1+?F6tGzrhboj9@;Y@-Y$;1UNd3FTy@Kesopkps%IL4CNFld>nNl)y+UZqNwu)u z8>5qRa*M`l|5*Q8iQQ0|QYFpu%XIuwER-RaS8~oYrJPIl?9@kcyPIPAOJL|a#!5Tj E15l gulp.1", - "lint": "jshint lib bin index.js --reporter node_modules/jshint-stylish/stylish.js --exclude node_modules", - "test": "npm run-script lint && mocha --reporter spec", - "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" - }, - "engineStrict": true, - "engines": { - "node": ">= 0.9" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://raw.githubusercontent.com/gulpjs/gulp/master/LICENSE" - } - ], - "gitHead": "b7486d8850f172f3533406c529510c7649a3a04f", - "bugs": { - "url": "https://github.com/gulpjs/gulp/issues" - }, - "_id": "gulp@3.8.9", - "_shasum": "90773dc79cb0b3087e5443c695b0f5a21548ccce", - "_from": "gulp@^3.8.9", - "_npmVersion": "2.1.4", - "_nodeVersion": "0.10.32", - "_npmUser": { - "name": "fractal", - "email": "contact@wearefractal.com" - }, - "maintainers": [ - { - "name": "fractal", - "email": "contact@wearefractal.com" - } - ], - "dist": { - "shasum": "90773dc79cb0b3087e5443c695b0f5a21548ccce", - "tarball": "http://registry.npmjs.org/gulp/-/gulp-3.8.9.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/gulp/-/gulp-3.8.9.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/spec/fixture/package.json.install b/spec/fixture/package.json.install deleted file mode 100644 index eb813027..00000000 --- a/spec/fixture/package.json.install +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "atom-build-fixture", - "description": "used to set up fixtures correctly for testing", - "private": true, - "engines": { - "node": "0.10.x" - }, - "dependencies": { - "grunt": "^0.4.5", - "grunt-cli": "^0.1.3", - "gulp": "^3.8.9" - } -} From 21a092119796dfbc79b9ba5b7172df99bbf00e85 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 28 Aug 2015 23:54:58 +0200 Subject: [PATCH 189/495] Use common spec-helpers package --- package.json | 5 ++-- spec/build-keymap-spec.js | 2 +- spec/build-spec.js | 2 +- spec/build-targets-spec.js | 2 +- spec/build-view-spec.js | 2 +- spec/build-visible-spec.js | 2 +- spec/spec-helpers.js | 52 -------------------------------------- 7 files changed, 8 insertions(+), 59 deletions(-) delete mode 100644 spec/spec-helpers.js diff --git a/package.json b/package.json index e5d6e88f..9111ee37 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,16 @@ "dependencies": { "ansi_up": "^1.3.0", "atom-space-pen-views": "^2.0.3", - "fs-extra": "^0.23.0", "getmac": "^1.0.7", "lodash": "^3.8.0", "node-uuid": "^1.4.3", - "temp": "^0.8.1", "tree-kill": "^0.1.1", "xregexp": "^2.0.0" }, "devDependencies": { + "fs-extra": "^0.23.0", + "temp": "^0.8.1", + "atom-build-spec-helpers": "^0.1.0", "jshint": "^2.5.11", "jscs": "^1.9.0" }, diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index d77a03a9..2fb5bfed 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -3,7 +3,7 @@ var fs = require('fs-extra'); var temp = require('temp'); -var specHelpers = require('./spec-helpers'); +var specHelpers = require('atom-build-spec-helpers'); describe('Keymap', function() { var directory = null; diff --git a/spec/build-spec.js b/spec/build-spec.js index f5c02f11..3791965b 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -4,7 +4,7 @@ var _ = require('lodash'); var fs = require('fs-extra'); var temp = require('temp'); -var specHelpers = require('./spec-helpers'); +var specHelpers = require('atom-build-spec-helpers'); describe('Build', function() { var goodNodefile = __dirname + '/fixture/package.json.node'; diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index d9fc659f..7ae27c20 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -4,7 +4,7 @@ var _ = require('lodash'); var fs = require('fs-extra'); var temp = require('temp'); -var specHelpers = require('./spec-helpers'); +var specHelpers = require('atom-build-spec-helpers'); describe('Target', function() { var directory = null; diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 957cb3ed..1518e6c6 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -3,7 +3,7 @@ var fs = require('fs-extra'); var temp = require('temp'); -var specHelpers = require('./spec-helpers'); +var specHelpers = require('atom-build-spec-helpers'); describe('BuildView', function() { diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index ed5927f2..d43f1441 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -3,7 +3,7 @@ var fs = require('fs-extra'); var temp = require('temp'); -var specHelpers = require('./spec-helpers'); +var specHelpers = require('atom-build-spec-helpers'); describe('Visible', function() { diff --git a/spec/spec-helpers.js b/spec/spec-helpers.js deleted file mode 100644 index b81dc673..00000000 --- a/spec/spec-helpers.js +++ /dev/null @@ -1,52 +0,0 @@ -'use babel'; -'use strict'; - -module.exports = { - _dispatchKeyboardEvent: function (type, element, key, ctrl, alt, shift, meta) { - var charCode = key.charCodeAt(0); - var unicode = 'U+00' + charCode.toString(16).toUpperCase(); - var e = document.createEvent('KeyboardEvent'); - e.initKeyboardEvent(type, true, true, null, unicode, 0, ctrl, alt, shift, meta); - document.dispatchEvent(e); - }, - - keyboardEvent: function (key, opts) { - var element = opts.element || document.activeElement; - this._dispatchKeyboardEvent('keydown', element, key, true, true, false, false); - this._dispatchKeyboardEvent('keypress', element, key, true, true, false, false); - this._dispatchKeyboardEvent('keyup', element, key, true, true, false, false); - }, - - dispatchKeyboardEvent: function (target, type, eventArgs) { - var e = document.createEvent('KeyboardEvent'); - e.initKeyboardEvent.apply(e, [ type ].concat(eventArgs)); - if (e.keyCode === 0) { - Object.defineProperty(e, 'keyCode', { - get: function() { return undefined; } - }); - } - return target.dispatchEvent(e); - }, - - keydown: function (key, opt) { - var unicode = 'U+' + key.charCodeAt(0).toString(16); - var element = opt.element || document.activeElement; - var eventArgs = [ true, true, null, unicode, 0, opt.ctrl, opt.alt, opt.shift, opt.meta ]; - this.dispatchKeyboardEvent(element, 'keydown', eventArgs); - this.dispatchKeyboardEvent(element, 'keypress', eventArgs); - this.dispatchKeyboardEvent(element, 'keyup', eventArgs); - }, - - vouch: function vouch(fn /* args... */) { - var args = Array.prototype.slice.call(arguments, 1); - return new Promise(function(resolve, reject) { - args.push(function(err, result) { - if (err) { - return reject(err); - } - resolve(result); - }); - fn.apply(null, args); - }); - } -}; From f817821c7b1be4eff3d2717930439202a58ba228 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 29 Aug 2015 23:16:01 +0200 Subject: [PATCH 190/495] Tools: Removed all references to Elixir --- lib/tools/Elixir.js | 29 ----------------------------- lib/tools/index.js | 1 - 2 files changed, 30 deletions(-) delete mode 100644 lib/tools/Elixir.js diff --git a/lib/tools/Elixir.js b/lib/tools/Elixir.js deleted file mode 100644 index 536db6e3..00000000 --- a/lib/tools/Elixir.js +++ /dev/null @@ -1,29 +0,0 @@ -'use babel'; -'use strict'; - -var fs = require('fs'); - -module.exports.niceName = 'Elixir'; - -module.exports.isEligable = function (path) { - return fs.existsSync(path + '/mix.exs'); -}; - -module.exports.settings = function (path) { - if (!atom.config.get('deprecated.tool.elixir')) { - atom.notifications.addWarning('Bundled `Elixir` build will be removed', { - dismissable: true, - detail: - 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + - 'You can install `build-elixir` (apm install build-elixir) at this time and you will be well prepared for the next release!' - }); - atom.config.set('deprecated.tool.elixir', true); - } - - return [ { - name: 'Elixir: default', - exec: 'mix', - args: [ 'compile' ], - sh: false - } ]; -}; diff --git a/lib/tools/index.js b/lib/tools/index.js index 9fd9af72..dfbe3478 100644 --- a/lib/tools/index.js +++ b/lib/tools/index.js @@ -14,6 +14,5 @@ module.exports = [ require('./npm_apm'), /* specific (builds only one thing) */ - require('./Elixir'), require('./Cargo') ]; From 063eb4978a9f643fcd8ecb89fa738663bf3ac8bf Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 29 Aug 2015 23:38:22 +0200 Subject: [PATCH 191/495] Tools: Removed all references to cargo --- lib/tools/Cargo.js | 44 -------------------------------------------- lib/tools/index.js | 3 --- 2 files changed, 47 deletions(-) delete mode 100644 lib/tools/Cargo.js diff --git a/lib/tools/Cargo.js b/lib/tools/Cargo.js deleted file mode 100644 index a5ecf7d4..00000000 --- a/lib/tools/Cargo.js +++ /dev/null @@ -1,44 +0,0 @@ -'use babel'; -'use strict'; - -var fs = require('fs'); - -module.exports.niceName = 'Cargo'; - -module.exports.isEligable = function (path) { - return fs.existsSync(path + '/Cargo.toml'); -}; - -module.exports.settings = function (path) { - if (!atom.config.get('deprecated.tool.cargo')) { - atom.notifications.addWarning('Bundled `Cargo` build will be removed', { - dismissable: true, - detail: - 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + - 'You can install `build-cargo` (apm install build-cargo) at this time and you will be well prepared for the next release!' - }); - atom.config.set('deprecated.tool.cargo', true); - } - - return [ { - name: 'Cargo: build', - exec: 'cargo', - args: [ 'build' ], - sh: false, - errorMatch: '(?.+.rs):(?\\d+):(?\\d+):' - }, - { - name: 'Cargo: test', - exec: 'cargo', - args: [ 'test' ], - sh: false, - errorMatch: '(?.+.rs):(?\\d+):(?\\d+):' - }, - { - name: 'Cargo: run', - exec: 'cargo', - args: [ 'run' ], - sh: false, - errorMatch: '(?.+.rs):(?\\d+):(?\\d+):' - }]; -}; diff --git a/lib/tools/index.js b/lib/tools/index.js index dfbe3478..9415206d 100644 --- a/lib/tools/index.js +++ b/lib/tools/index.js @@ -12,7 +12,4 @@ module.exports = [ /* semi-generic (may trigger other build scripts) */ require('./npm_apm'), - - /* specific (builds only one thing) */ - require('./Cargo') ]; From 19513d3e948faacc9724ab1298e795deae04c9a3 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 29 Aug 2015 23:56:17 +0200 Subject: [PATCH 192/495] Tools: Removed references to npm/apm --- lib/{tools => }/atom-build.js | 0 lib/build.js | 9 ++- lib/tools/index.js | 15 ----- lib/tools/npm_apm.js | 56 ----------------- spec/build-spec.js | 97 ------------------------------ spec/fixture/package.json.atom | 11 ---- spec/fixture/package.json.node | 11 ---- spec/fixture/package.json.noengine | 5 -- 8 files changed, 4 insertions(+), 200 deletions(-) rename lib/{tools => }/atom-build.js (100%) delete mode 100644 lib/tools/index.js delete mode 100644 lib/tools/npm_apm.js delete mode 100644 spec/fixture/package.json.atom delete mode 100644 spec/fixture/package.json.node delete mode 100644 spec/fixture/package.json.noengine diff --git a/lib/tools/atom-build.js b/lib/atom-build.js similarity index 100% rename from lib/tools/atom-build.js rename to lib/atom-build.js diff --git a/lib/build.js b/lib/build.js index 69c59bb5..ad503ca2 100644 --- a/lib/build.js +++ b/lib/build.js @@ -13,8 +13,7 @@ var TargetsView = require('./targets-view'); var BuildView = require('./build-view'); var GoogleAnalytics = require('./google-analytics'); var ErrorMatcher = require('./error-matcher'); -var tools = require('./tools'); -var extra_tools = []; +var tools = [ require('./atom-build') ]; function BuildError(name, message) { this.name = name; @@ -203,7 +202,7 @@ module.exports = { throw new BuildError('No active project', 'No project is active, don\'t know what to build...'); } - return _.filter(tools.concat(extra_tools), function (tool) { + return _.filter(tools, function (tool) { return tool.isEligable(path); }); }) @@ -469,9 +468,9 @@ module.exports = { if (!(builders instanceof Array)) { builders = [ builders ]; } - extra_tools = _.union(extra_tools, builders); + tools = _.union(tools, builders); return new Disposable(function () { - extra_tools = _.difference(extra_tools, builders); + tools = _.difference(tools, builders); }); } }; diff --git a/lib/tools/index.js b/lib/tools/index.js deleted file mode 100644 index 9415206d..00000000 --- a/lib/tools/index.js +++ /dev/null @@ -1,15 +0,0 @@ -'use babel'; -'use strict'; - -/* -Build tools available to atom-build. -These are sorted in order of priority -and divided into groups as seen by comments below -*/ -module.exports = [ - /* generic (can be configured to do anything) */ - require('./atom-build'), - - /* semi-generic (may trigger other build scripts) */ - require('./npm_apm'), -]; diff --git a/lib/tools/npm_apm.js b/lib/tools/npm_apm.js deleted file mode 100644 index 71ec9ad9..00000000 --- a/lib/tools/npm_apm.js +++ /dev/null @@ -1,56 +0,0 @@ -'use babel'; -'use strict'; - -var path = require('path'); -var fs = require('fs'); - -module.exports.niceName = 'npm or apm'; - -module.exports.isEligable = function (cwd) { - if (!fs.existsSync(path.join(cwd, 'package.json'))) { - return false; - } - - var realPackage = fs.realpathSync(path.join(cwd, 'package.json')); - delete require.cache[realPackage]; - var pkg = require(realPackage); - - if (!pkg.engines || (!pkg.engines.atom && !pkg.engines.node)) { - return false; - } - - return true; -}; - -module.exports.settings = function (cwd) { - if (!atom.config.get('deprecated.tool.npmapm')) { - atom.notifications.addWarning('Bundled `npm` and `apm` build will be removed', { - dismissable: true, - detail: - 'You are using a bundled tool for `build` which will have to be installed seperately next version of `build`.\n' + - 'You can install `build-npm-apm` (apm install build-npm-apm) at this time and you will be well prepared for the next release!' - }); - atom.config.set('deprecated.tool.npmapm', true); - } - - var realPackage = fs.realpathSync(path.join(cwd, 'package.json')); - var pkg = require(realPackage); - - var executableExtension = /^win/.test(process.platform) ? '.cmd' : ''; - var config = [ { - name: pkg.engines.node ? 'npm: default' : 'apm: default', - exec: (pkg.engines.node ? 'npm' : 'apm') + executableExtension, - args: [ '--color=always', 'install' ], - sh: false - } ]; - - for (var script in pkg.scripts) { - config.push({ - name: 'npm: ' + script, - exec: 'npm', - args: [ '--color=always', 'run', script ], - sh: false - }); - } - return config; -}; diff --git a/spec/build-spec.js b/spec/build-spec.js index 3791965b..89e9e4ee 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,15 +1,11 @@ 'use babel'; 'use strict'; -var _ = require('lodash'); var fs = require('fs-extra'); var temp = require('temp'); var specHelpers = require('atom-build-spec-helpers'); describe('Build', function() { - var goodNodefile = __dirname + '/fixture/package.json.node'; - var goodAtomfile = __dirname + '/fixture/package.json.atom'; - var badPackageJsonfile = __dirname + '/fixture/package.json.noengine'; var goodAtomBuildfile = __dirname + '/fixture/.atom-build.json'; var shellAtomBuildfile = __dirname + '/fixture/.atom-build.shell.json'; var replaceAtomBuildFile = __dirname + '/fixture/.atom-build.replace.json'; @@ -150,99 +146,6 @@ describe('Build', function() { }); }); - describe('when build is triggered with package.json file', function() { - it('should show the build window if it is node engine', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: npm/); - }); - }); - - it('should show the build window if it is atom engine', function() { - if (process.env.TRAVIS) { - return; - } - - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waitsFor(function() { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }, 'build to be successful', 10000); - - runs(function() { - expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/^Executing: apm/); - }); - }); - - it('should not do anything if engines are not available in the file', function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'package.json', fs.readFileSync(badPackageJsonfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); - - waits(1000); - - runs(function() { - expect(workspaceElement.querySelector('.build')).not.toExist(); - }); - }); - - it('should list scripts as build targets', function () { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodNodefile)); - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:select-active-target'); - }); - - waitsFor(function () { - return workspaceElement.querySelector('.select-list li.build-target'); - }); - - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); - expect(targets).toEqual([ 'npm: default', 'npm: custom script' ]); - }); - }); - - it('should list package.json files with engine atom scripts as run by NPM', function () { - expect(workspaceElement.querySelector('.build')).not.toExist(); - - fs.writeFileSync(directory + 'package.json', fs.readFileSync(goodAtomfile)); - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:select-active-target'); - }); - - waitsFor(function () { - return workspaceElement.querySelector('.select-list li.build-target'); - }); - - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); - expect(targets).toEqual([ 'apm: default', 'npm: custom script' ]); - }); - }); - }); - describe('when custom .atom-build.json is available', function() { it('should show the build window', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); diff --git a/spec/fixture/package.json.atom b/spec/fixture/package.json.atom deleted file mode 100644 index 05517d79..00000000 --- a/spec/fixture/package.json.atom +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "test-proj", - "version": "0.1.1", - "private": true, - "engines": { - "atom": ">=0.50.0" - }, - "scripts": { - "custom script": "echo 'custom script'" - } -} diff --git a/spec/fixture/package.json.node b/spec/fixture/package.json.node deleted file mode 100644 index ec03ae51..00000000 --- a/spec/fixture/package.json.node +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "test-proj", - "version": "0.1.1", - "private": true, - "engines": { - "node": "0.10.x" - }, - "scripts": { - "custom script": "echo 'custom script'" - } -} diff --git a/spec/fixture/package.json.noengine b/spec/fixture/package.json.noengine deleted file mode 100644 index 735b5137..00000000 --- a/spec/fixture/package.json.noengine +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "test-proj", - "version": "0.1.1", - "private": true -} From 856cc0080ac1bdd1a2bfbbfbd208129f66f1b712 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 30 Aug 2015 11:59:39 +0200 Subject: [PATCH 193/495] README: list plugins --- README.md | 36 +++++++----------------------------- build-tools.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 build-tools.md diff --git a/README.md b/README.md index aaac262a..aa14722d 100644 --- a/README.md +++ b/README.md @@ -13,35 +13,13 @@ Automatically build your project inside your new favorite editor, Atom. ![work work](https://noseglid.github.io/atom-build.gif) -Supported build tools: - - 1. Custom by [specifying your own build command](#custom-build-command) - * Supports multiple targets. - * Supports error matching. - 1. [NodeJS](http://nodejs.org) (runs `npm install`) - if `package.json` exists where `engines['node']` is set - 1. [Atom](http://atom.io) (runs `apm install`) - if `package.json` exists where `engines['atom']` is set - 1. [Grunt](http://gruntjs.com/) - if `Gruntfile.js` exists - * Supports multiple targets. - 1. [Gulp](http://gulpjs.com/) - if `gulpfile.js` exists - * Supports multiple targets. - 1. [GNU Make](https://www.gnu.org/software/make/) - if `Makefile` exists - 1. [Elixir](http://elixir-lang.org/) - if `mix.exs` exists - 1. [Cargo](http://doc.crates.io) - if `Cargo.toml` exists - * Supports error matching. - -If multiple viable build options are found, `atom-build` will -prioritise according to the list above. For instance, if `package.json` and -`Gruntfile.js` are both available in the root folder, `npm install` will be -executed by `atom-build`. - -If you need to run `grunt`, `gulp` or other tool to build your project, then you can utilize the [postinstall-script](https://www.npmjs.org/doc/misc/npm-scripts.html) of package.json. This will also help you if grunt is run as a node module since it -will be downloaded (via `npm install`) prior. - - -## Specifying a custom build command - -If the built-in defaults are not enough to suit your needs, you can specify -exactly what to execute. Create a file named `.atom-build.json` in your project root: + +## Specifying a build command +You can check out [the plugins list](build-tools.md) for common build tools. Install them as +you would any other package! + +If no build tool is enough to suit your needs, you can create a file named `.atom-build.json` +in your project root, and specify exactly how your project is built: { "cmd": "", diff --git a/build-tools.md b/build-tools.md new file mode 100644 index 00000000..62bb371f --- /dev/null +++ b/build-tools.md @@ -0,0 +1,30 @@ +# Community build tools for [atom-build](https://atom.io/packages/build) + +| Tool | Plugin | +|----------------|---------------------------| +| [GNU Make](1) | [atom-build-make](2) | +| [gulp](3) | [atom-build-gulp](4) | +| [grunt](5) | [atom-build-grunt](6) | +| [npm](7) | [atom-build-npm-apm](8) | +| [apm](9) | [atom-build-npm-apm](8) | +| [Cargo](10) | [atom-build-cargo](11) | +| [Elixir](12) | [atom-build-elixir](13) | +| [Markdown](14) | [atom-build-markdown](15) | + +Have you created a build plugin and want it displayed here? Create a PR modifying this list! + +[1]: https://www.gnu.org/software/make/ +[2]: https://atom.io/packages/build-make +[3]: http://gulpjs.com/ +[4]: https://atom.io/packages/build-gulp +[5]: http://gruntjs.com/ +[6]: https://atom.io/packages/build-grunt +[7]: https://www.npmjs.com/ +[8]: https://atom.io/packages/build-npm-apm +[9]: https://github.com/atom/apm +[10]: https://crates.io/ +[11]: https://atom.io/packages/build-cargo +[12]: http://elixir-lang.org/ +[13]: https://atom.io/packages/build-elixir +[14]: http://daringfireball.net/projects/markdown/ +[15]: https://atom.io/packages/build-markdown From 16ed36dee24cb847a9582a902d750d2900754323 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 30 Aug 2015 12:02:49 +0200 Subject: [PATCH 194/495] README: Fix links --- build-tools.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/build-tools.md b/build-tools.md index 62bb371f..4f6fb2b4 100644 --- a/build-tools.md +++ b/build-tools.md @@ -2,16 +2,17 @@ | Tool | Plugin | |----------------|---------------------------| -| [GNU Make](1) | [atom-build-make](2) | -| [gulp](3) | [atom-build-gulp](4) | -| [grunt](5) | [atom-build-grunt](6) | -| [npm](7) | [atom-build-npm-apm](8) | -| [apm](9) | [atom-build-npm-apm](8) | -| [Cargo](10) | [atom-build-cargo](11) | -| [Elixir](12) | [atom-build-elixir](13) | -| [Markdown](14) | [atom-build-markdown](15) | +| [GNU Make][1] | [atom-build-make][2] | +| [gulp][3] | [atom-build-gulp][4] | +| [grunt][5] | [atom-build-grunt][6] | +| [npm][7] | [atom-build-npm-apm][8] | +| [apm][9] | [atom-build-npm-apm][8] | +| [Cargo][10] | [atom-build-cargo][11] | +| [Elixir][12] | [atom-build-elixir][13] | +| [Markdown][14] | [atom-build-markdown][15] | -Have you created a build plugin and want it displayed here? Create a PR modifying this list! +Have you created a build plugin and want it displayed here? +Create a PR modifying this list. [1]: https://www.gnu.org/software/make/ [2]: https://atom.io/packages/build-make From b712fd80d0ca1c7b52a975ffa0586083762bbd8e Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 20:46:11 +0200 Subject: [PATCH 195/495] README: Added Gradle --- build-tools.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-tools.md b/build-tools.md index 4f6fb2b4..3a39a53a 100644 --- a/build-tools.md +++ b/build-tools.md @@ -10,6 +10,7 @@ | [Cargo][10] | [atom-build-cargo][11] | | [Elixir][12] | [atom-build-elixir][13] | | [Markdown][14] | [atom-build-markdown][15] | +| [Gradle][16] | [atom-build-gradle][17] | Have you created a build plugin and want it displayed here? Create a PR modifying this list. @@ -29,3 +30,5 @@ Create a PR modifying this list. [13]: https://atom.io/packages/build-elixir [14]: http://daringfireball.net/projects/markdown/ [15]: https://atom.io/packages/build-markdown +[16]: https://gradle.org/ +[17]: https://atom.io/packages/build-gradle From 9e0e0ec3c6256a329dd755d36ae2aba0c13437f2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 20:47:22 +0200 Subject: [PATCH 196/495] README: added JPM --- build-tools.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-tools.md b/build-tools.md index 3a39a53a..82204642 100644 --- a/build-tools.md +++ b/build-tools.md @@ -11,6 +11,7 @@ | [Elixir][12] | [atom-build-elixir][13] | | [Markdown][14] | [atom-build-markdown][15] | | [Gradle][16] | [atom-build-gradle][17] | +| [JPM][18] | [build-jpm][19] | Have you created a build plugin and want it displayed here? Create a PR modifying this list. @@ -32,3 +33,5 @@ Create a PR modifying this list. [15]: https://atom.io/packages/build-markdown [16]: https://gradle.org/ [17]: https://atom.io/packages/build-gradle +[18]: https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/jpm +[19]: https://atom.io/packages/build-jpm From 2616ffc202257d4ee6135a1718d5e5205c764878 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 20:48:09 +0200 Subject: [PATCH 197/495] README: Corrected package name --- build-tools.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build-tools.md b/build-tools.md index 82204642..5c63bd3d 100644 --- a/build-tools.md +++ b/build-tools.md @@ -2,15 +2,15 @@ | Tool | Plugin | |----------------|---------------------------| -| [GNU Make][1] | [atom-build-make][2] | -| [gulp][3] | [atom-build-gulp][4] | -| [grunt][5] | [atom-build-grunt][6] | -| [npm][7] | [atom-build-npm-apm][8] | -| [apm][9] | [atom-build-npm-apm][8] | -| [Cargo][10] | [atom-build-cargo][11] | -| [Elixir][12] | [atom-build-elixir][13] | -| [Markdown][14] | [atom-build-markdown][15] | -| [Gradle][16] | [atom-build-gradle][17] | +| [GNU Make][1] | [build-make][2] | +| [gulp][3] | [build-gulp][4] | +| [grunt][5] | [build-grunt][6] | +| [npm][7] | [build-npm-apm][8] | +| [apm][9] | [build-npm-apm][8] | +| [Cargo][10] | [build-cargo][11] | +| [Elixir][12] | [build-elixir][13] | +| [Markdown][14] | [build-markdown][15] | +| [Gradle][16] | [build-gradle][17] | | [JPM][18] | [build-jpm][19] | Have you created a build plugin and want it displayed here? From d51ce75a9d30b5b6585e883c49340995cb059dcc Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 23 Sep 2015 20:49:30 +0200 Subject: [PATCH 198/495] README: Clarified wording --- build-tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools.md b/build-tools.md index 5c63bd3d..97cab24c 100644 --- a/build-tools.md +++ b/build-tools.md @@ -14,7 +14,7 @@ | [JPM][18] | [build-jpm][19] | Have you created a build plugin and want it displayed here? -Create a PR modifying this list. +Create a pull request modifying this list. [1]: https://www.gnu.org/software/make/ [2]: https://atom.io/packages/build-make From ed23e448daad6fc54e925e66ee2429703548eb93 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 26 Sep 2015 10:11:47 +0200 Subject: [PATCH 199/495] Build provders get called with context Help re-use of any information that might be retrieved in `isEligable` once `settings` is called. --- README.md | 6 +++++- lib/build.js | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aa14722d..89cc5a2d 100644 --- a/README.md +++ b/README.md @@ -154,10 +154,14 @@ argument, `path`, which is the root folder of the currently active project in At It should return `true` or `false` indicating if it can build that folder into something sensible. Typically look for the existence of a build file such as `gulpfile.js` or `Makefile`. -`settings` must return a promise. It is called when it is time to build the project. +`settings` can return a Promise or an object.. It is called when it is time to build the project. It can provide anything which is allowed by the [custom build configuration](#custom-build-config). This includes the command, `cmd`, to execute, any arguments, `args`, and so on. +`isEligable` and `settings` will be called with the same value for `this` (which is an empty object at first). If you have to make +any time consuming computation is `isEligable` it may be wise to store that in `this` and +reuse it in `settings`. + ## Analytics The `atom-build` package uses google analytics to keep track of which features are in use diff --git a/lib/build.js b/lib/build.js index ad503ca2..279829a3 100644 --- a/lib/build.js +++ b/lib/build.js @@ -203,13 +203,14 @@ module.exports = { } return _.filter(tools, function (tool) { - return tool.isEligable(path); + tool.ctx = {}; + return tool.isEligable.apply(tool.ctx, [ path ]); }); }) .then(function (tools) { return Promise.all(_.map(tools, function (tool) { GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); - return tool.settings(path); + return tool.settings.apply(tool.ctx, [ path ]); })); }) .then(_.flatten) From 2cccd4a8acf3055fd2f3c749b8a18cba04d5fd2a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 10 Oct 2015 16:08:12 +0200 Subject: [PATCH 200/495] Support for CSON custom file Custom file may be written in CSON. The file should in such case be named `.atom-build.cson`. JSON and CSON files may be present at the same time, however, unless they specify unique names they will overwrite each others configs. Fixes #178 --- lib/atom-build.js | 87 ++++++++++++++++++++++++++++----------- lib/build.js | 39 +++++++----------- package.json | 3 +- spec/build-keymap-spec.js | 2 +- 4 files changed, 81 insertions(+), 50 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index 0802cdfe..6828f3c7 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -4,37 +4,78 @@ var path = require('path'); var fs = require('fs'); var _ = require('lodash'); +var CSON = require('cson-parser'); -module.exports.niceName = 'Custom file (.atom-build.json)'; +module.exports.niceName = 'Custom file'; + +function getConfig(file) { + var realFile = fs.realpathSync(file); + delete require.cache[realFile]; + switch (path.extname(file)) { + case '.json': + return require(realFile); + + case '.cson': + var content = fs.readFileSync(realFile); + return CSON.parse(content); + } +} + +function createBuildConfig(build, name) { + return { + name: 'Custom: ' + name, + exec: build.cmd, + env: build.env, + args: build.args, + cwd: build.cwd, + sh: build.sh, + errorMatch: build.errorMatch, + keymap: build.keymap + }; +} module.exports.isEligable = function (cwd) { - return fs.existsSync(path.join(cwd, '.atom-build.json')); + this.files = _([ '.atom-build.json', '.atom-build.cson' ]) + .map(file => { return path.join(cwd, file); }) + .filter(fs.existsSync) + .value(); + return 0 < this.files.length; }; module.exports.settings = function (cwd) { - var realAtomBuild = fs.realpathSync(cwd + '/.atom-build.json'); - delete require.cache[realAtomBuild]; - - var createBuildConfig = function(build, name) { - return { - name: 'Custom: ' + name, - exec: build.cmd, - env: build.env, - args: build.args, - cwd: build.cwd, - sh: build.sh, - errorMatch: build.errorMatch, - keymap: build.keymap - }; - }; - - var build = require(realAtomBuild); - var config = []; - config.push(createBuildConfig(build, build.name || 'default')); - _.forEach(build.targets || [], function (target, name) { - config.push(createBuildConfig(target, name)); + let config = []; + this.files.map(getConfig).forEach(build => { + config.push(createBuildConfig(build, build.name || 'default')); + _.forEach(build.targets || [], (target, name) => { + config.push(createBuildConfig(target, name)); + }); }); return config; }; + +let fileWatchers = []; +module.exports.on = function (ev, cb) { + if ('refresh' !== ev || !this.files) { + return; + } + + fileWatchers.forEach(watcher => { + watcher.close(); + }); + + fileWatchers = this.files.map(file => { + return fs.watch(file, cb); + }); +}; + +module.exports.off = function (ev) { + if ('refresh' !== ev) { + return; + } + + fileWatchers.forEach(watcher => { + watcher.close(); + }); +}; diff --git a/lib/build.js b/lib/build.js index 279829a3..b141b6b1 100644 --- a/lib/build.js +++ b/lib/build.js @@ -143,9 +143,9 @@ module.exports = { }, deactivate: function() { - if (this.customFileWatcher) { - this.customFileWatcher.close(); - } + tools.forEach(tool => { + tool.off('refresh'); + }); if (this.child) { kill(this.child.pid, 'SIGKILL'); } @@ -183,20 +183,8 @@ module.exports = { refreshTargets: function() { var path = this.activePath(); var prioritizedTarget; - var customFile = path + '/.atom-build.json'; - - if (this.customFileWatcher) { - this.customFileWatcher.close(); - this.customFileWatcher = undefined; - } return Promise.resolve(tools) - .then(function () { - this.customFileWatcher = fs.watch(customFile, function () { - this.refreshTargets(); - }.bind(this)); - }.bind(this)) - .catch(function(err) { /* Unable to watch file. Updates to custom file will require manual refresh */ }) .then(function () { if (!path) { throw new BuildError('No active project', 'No project is active, don\'t know what to build...'); @@ -207,25 +195,26 @@ module.exports = { return tool.isEligable.apply(tool.ctx, [ path ]); }); }) - .then(function (tools) { - return Promise.all(_.map(tools, function (tool) { + .then(tools => { + return Promise.all(_.map(tools, tool => { GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); + tool.on.apply(tool.ctx, [ 'refresh', this.refreshTargets.bind(this) ]); return tool.settings.apply(tool.ctx, [ path ]); })); }) .then(_.flatten) - .then(function (settings) { + .then(settings => { if (0 === _.size(settings)) { throw new BuildError('No eligible build tool.', 'No tool can provide any build configurations.'); } prioritizedTarget = settings[0].name; - return _.map(settings, function (s) { + return _.map(settings, (s) => { return [ s.name, _.defaults(s, this.cmdDefaults(path)) ]; - }.bind(this)); - }.bind(this)) + }); + }) .then(_.zipObject) - .then(function (targets) { + .then(targets => { if (_.isNull(this.activeTarget) || _.isUndefined(targets[this.activeTarget])) { /* Active target has been removed or not set. Set it to the highest prio target */ this.activeTarget = prioritizedTarget; @@ -235,7 +224,7 @@ module.exports = { target.dispose(); // Gets rid of keymaps and commands registered }); - _.forEach(targets, function (target, targetName) { + _.forEach(targets, (target, targetName) => { if (!target.keymap) { target.dispose = _.noop; return; @@ -251,10 +240,10 @@ module.exports = { keymapDispose.dispose(); commandDispose.dispose(); }; - }.bind(this)); + }); return (this.targets = targets); - }.bind(this)); + }); }, selectActiveTarget: function() { diff --git a/package.json b/package.json index 9111ee37..39c26b7e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "lodash": "^3.8.0", "node-uuid": "^1.4.3", "tree-kill": "^0.1.1", - "xregexp": "^2.0.0" + "xregexp": "^2.0.0", + "cson-parser": "^1.2.0" }, "devDependencies": { "fs-extra": "^0.23.0", diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index 2fb5bfed..0970b2cb 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -200,7 +200,7 @@ describe('Keymap', function() { })); }); - waits(300); // .atom-build.json is reloaded automatically + waits(300); // Custom file is reloaded automatically runs(function () { specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); From d50f848595386924980430c27914776efa13e3ef Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 10 Oct 2015 16:30:40 +0200 Subject: [PATCH 201/495] Only call on/off if tool supports it --- lib/build.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index b141b6b1..dba7c35f 100644 --- a/lib/build.js +++ b/lib/build.js @@ -144,7 +144,7 @@ module.exports = { deactivate: function() { tools.forEach(tool => { - tool.off('refresh'); + tool.off.apply(tool.ctx, [ 'refresh' ]); }); if (this.child) { kill(this.child.pid, 'SIGKILL'); @@ -198,7 +198,12 @@ module.exports = { .then(tools => { return Promise.all(_.map(tools, tool => { GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); - tool.on.apply(tool.ctx, [ 'refresh', this.refreshTargets.bind(this) ]); + + if (tool.on) { + tool.off.apply(tool.ctx, [ 'refresh' ]); + tool.on.apply(tool.ctx, [ 'refresh', this.refreshTargets.bind(this) ]); + } + return tool.settings.apply(tool.ctx, [ path ]); })); }) From 95af8b86afa0f5cb5adbe7be7ef6253795ec0703 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 10 Oct 2015 16:39:32 +0200 Subject: [PATCH 202/495] README: Added info about on/off --- README.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 89cc5a2d..49cc0a6d 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,9 @@ To jump to the first error you can use `cmd-alt-h` (OS X) or `ctrl-alt-h` (Linux Another package may provide build information to the `build`-package by implementing its service API. The package should integrate via the service API. This is typically done in `package.json`: -```json +```javascript { - + // "providedServices": { "builder": { "description": "Description of the build configurations this package gives", @@ -142,7 +142,9 @@ object in return: { niceName: 'string', isEligable: function (path) {}, - settings: function (path) {} + settings: function (path) {}, + on: function (ev, callback) {}, //optional + off: function (ev), //optional } ``` @@ -158,8 +160,17 @@ sensible. Typically look for the existence of a build file such as `gulpfile.js` It can provide anything which is allowed by the [custom build configuration](#custom-build-config). This includes the command, `cmd`, to execute, any arguments, `args`, and so on. -`isEligable` and `settings` will be called with the same value for `this` (which is an empty object at first). If you have to make -any time consuming computation is `isEligable` it may be wise to store that in `this` and +_[optional]_ `on` will be called with a string which is the name of an event the build tool provider can emit. The build +tool provider should call the `callback` when the specified event occurs. Events `build` may ask for include: + * `refresh` - call the callback if you want to force `build` to refresh all targets. + this is common after the build file has been altered. + +_[optional]_ `off` will be called when `build` is no longer interested in that event. It may be because +`build` is being deactivated, or refreshing its state. `build` will never call `off` for an event unless it has +previoused registered a listener via `on` first. + +All functions will be called with the same value for `this` (which is an empty object at first). If you have to make +any time consuming computation in for instance `isEligable` it may be wise to store the result in `this` and reuse it in `settings`. ## Analytics From 5135b2d7a706ff96a3113d4b3013d62dce58f659 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 10 Oct 2015 17:15:25 +0200 Subject: [PATCH 203/495] If `cmd` or `cwd` is invalid. Let user know Fixes #199 --- lib/build.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/build.js b/lib/build.js index 279829a3..3d293497 100644 --- a/lib/build.js +++ b/lib/build.js @@ -340,21 +340,28 @@ module.exports = { ); this.stdout = new Buffer(0); - this.child.stdout.on('data', function (buffer) { + this.child.stdout.on('data', (buffer) => { this.stdout = Buffer.concat([ this.stdout, buffer ]); this.buildView.append(buffer); - }.bind(this)); + }); this.stderr = new Buffer(0); - this.child.stderr.on('data', function (buffer) { + this.child.stderr.on('data', (buffer) => { this.stderr = Buffer.concat([ this.stderr, buffer ]); this.buildView.append(buffer); - }.bind(this)); + }); - this.child.on('error', function(err) { + this.child.on('error', (err) => { this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec + '\n'); - this.buildView.append(/\s/.test(this.cmd.exec) ? '`cmd` cannot contain space. Use `args` for arguments.\n' : ''); - }.bind(this)); + + if (/\s/.test(this.cmd.exec) && !this.cmd.sh) { + this.buildView.append('`cmd` cannot contain space. Use `args` for arguments.\n'); + } + + if ('ENOENT' === err.code) { + this.buildView.append('Make sure `cmd` and `cwd` exists and have correct access permissions.'); + } + }); this.child.on('close', function(exitCode) { this.buildView.buildFinished(0 === exitCode); From bf80b5309f11b49ff8adafe5ceb75628734a9af2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 10 Oct 2015 18:06:39 +0200 Subject: [PATCH 204/495] Calling dialog commands without dialog Make sure dialog exists before calling commands on it. Fixes #202 --- lib/build.js | 6 ++++-- spec/build-confirm-spec.js | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 279829a3..cdf0169d 100644 --- a/lib/build.js +++ b/lib/build.js @@ -114,8 +114,10 @@ module.exports = { document.activeElement.click(); }); atom.commands.add('atom-workspace', 'build:no-confirm', function() { - GoogleAnalytics.sendEvent('build', 'not confirmed'); - this.saveConfirmView.cancel(); + if (this.saveConfirmView) { + GoogleAnalytics.sendEvent('build', 'not confirmed'); + this.saveConfirmView.cancel(); + } }.bind(this)); atom.workspace.observeTextEditors(function(editor) { diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 5e11da5f..1549c7b4 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -90,6 +90,11 @@ describe('Confirm', function() { }); }); + it('should not do anything if issuing no-confirm whithout the dialog', function () { + expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + atom.commands.dispatch(workspaceElement, 'build:no-confirm'); + }); + it('should not confirm if a TextEditor edits an unsaved file', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); From b0e05323c77966f39caddcec8725792f3a2f1a2b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 11 Oct 2015 12:16:52 +0200 Subject: [PATCH 205/495] ErrorMatcher: Do not prepend cwd multiple times `cwd` should only be prepended once, not once for every error match issued. Fixes #194 --- lib/error-matcher.js | 15 ++++++------ spec/build-error-match-spec.js | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 9c3fac45..8e61579a 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -45,28 +45,29 @@ module.exports = (function () { } this.currentMatch.push(this.currentMatch.shift()); - if (!match.file) { + let file = match.file; + if (!file) { return this.emit('error', 'Did not match any file. Don\'t know what to open.'); } - if (!path.isAbsolute(match.file)) { - match.file = this.cwd + path.sep + match.file; + if (!path.isAbsolute(file)) { + file = this.cwd + path.sep + file; } var row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ var col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ - fs.exists(match.file, function (exists) { + fs.exists(file, (exists) => { if (!exists) { - return this.emit('error', 'Matched file does not exist: ' + match.file); + return this.emit('error', 'Matched file does not exist: ' + file); } - atom.workspace.open(match.file, { + atom.workspace.open(file, { initialLine: row, initialColumn: col, searchAllPanes: true }); this.emit('matched', match.id); - }.bind(this)); + }); }; ErrorMatcher.prototype._parse = function () { diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 5a208db9..27fcc1ee 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -301,6 +301,51 @@ describe('Error Match', function() { }); }); + it('should prepend `cwd` to the relative matched file if set', function () { + var atomBuild = { + cmd: 'echo __.atom-build.json__ && exit 1', + cwd: directory, + errorMatch: '__(?.+)__' + }; + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify(atomBuild)); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function () { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(function () { + return atom.commands.dispatch(workspaceElement, 'build:error-match-first'); + }); + + waitsFor(function () { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function () { + // Error match one more time to make sure `cwd` isn't prepended multiple times + atom.workspace.getActivePaneItem().destroy(); + }); + + waitsFor(function () { + return !atom.workspace.getActiveTextEditor(); + }); + + runs(function () { + return atom.commands.dispatch(workspaceElement, 'build:error-match-first'); + }); + + waitsFor(function () { + return atom.workspace.getActiveTextEditor(); + }); + + runs(function () { + var editor = atom.workspace.getActiveTextEditor(); + expect(editor.getPath()).toEqual(directory + '.atom-build.json'); + }); + }); + it('should auto match error on failed build when config is set', function () { atom.config.set('build.scrollOnError', true); From e1d83fe38a602f6754c2bb2599950c0380562876 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 11 Oct 2015 17:09:52 +0200 Subject: [PATCH 206/495] fixed escaping bug --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 69382a8c..2d4c84b5 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -230,7 +230,7 @@ module.exports = (function() { BuildView.prototype._render = function() { var string = _.escape(this.buffer.toString('utf8')); _.forEach(this.links, function (link, index) { - var replaceRegex = new RegExp(_.escapeRegExp(link.text), 'g'); + var replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); }); this.output.html(ansi_up.ansi_to_html(string)); From ed6f0a5860cedc48875c36c86431ca217064fb72 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 11 Oct 2015 17:19:19 +0200 Subject: [PATCH 207/495] Use ES6 style function context bind --- lib/build.js | 54 ++++++++++++++++++++++---------------------- lib/error-matcher.js | 4 ++-- lib/targets-view.js | 4 ++-- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/build.js b/lib/build.js index 9fbfeec8..bee90190 100644 --- a/lib/build.js +++ b/lib/build.js @@ -113,20 +113,20 @@ module.exports = { GoogleAnalytics.sendEvent('build', 'confirmed'); document.activeElement.click(); }); - atom.commands.add('atom-workspace', 'build:no-confirm', function() { + atom.commands.add('atom-workspace', 'build:no-confirm', () => { if (this.saveConfirmView) { GoogleAnalytics.sendEvent('build', 'not confirmed'); this.saveConfirmView.cancel(); } - }.bind(this)); + }); - atom.workspace.observeTextEditors(function(editor) { - editor.onDidSave(function(event) { + atom.workspace.observeTextEditors((editor) => { + editor.onDidSave((event) => { if (atom.config.get('build.buildOnSave')) { this.build('save'); } - }.bind(this)); - }.bind(this)); + }); + }); this.errorMatcher.on('error', function (message) { atom.notifications.addError('Error matching failed!', { detail: message }); @@ -210,18 +210,18 @@ module.exports = { })); }) .then(_.flatten) - .then(settings => { + .then((settings) => { if (0 === _.size(settings)) { throw new BuildError('No eligible build tool.', 'No tool can provide any build configurations.'); } prioritizedTarget = settings[0].name; - return _.map(settings, (s) => { - return [ s.name, _.defaults(s, this.cmdDefaults(path)) ]; + return _.map(settings, (setting) => { + return [ setting.name, _.defaults(setting, this.cmdDefaults(path)) ]; }); }) .then(_.zipObject) - .then(targets => { + .then((targets) => { if (_.isNull(this.activeTarget) || _.isUndefined(targets[this.activeTarget])) { /* Active target has been removed or not set. Set it to the highest prio target */ this.activeTarget = prioritizedTarget; @@ -257,16 +257,16 @@ module.exports = { var targetsView = new TargetsView(); targetsView.setLoading('Loading project build targets...\u2026'); - this.refreshTargets().then(function (targets) { + this.refreshTargets().then((targets) => { targetsView.setActiveTarget(this.activeTarget); targetsView.setItems(_.keys(targets)); return targetsView.awaitSelection(); - }.bind(this)).then(function(newTarget) { + }).then((newTarget) => { this.activeTarget = newTarget; var workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); - }.bind(this)).catch(function (err) { + }).catch(function (err) { targetsView.setError(err.message); }); }, @@ -308,10 +308,10 @@ module.exports = { this.match = []; Promise.resolve() - .then(function () { + .then(() => { return (this.activeTarget) ? this.targets : this.refreshTargets(); - }.bind(this)) - .then(function (targets) { + }) + .then((targets) => { this.cmd = targets[targetName ? targetName : this.activeTarget]; GoogleAnalytics.sendEvent('build', 'triggered'); @@ -321,9 +321,9 @@ module.exports = { } var env = _.extend(_.clone(process.env), this.cmd.env); - _.each(env, function(value, key, list) { + _.each(env, (value, key, list) => { list[key] = this.replace(value); - }.bind(this)); + }); var args = _.map(this.cmd.args, this.replace.bind(this)); @@ -359,13 +359,13 @@ module.exports = { } }); - this.child.on('close', function(exitCode) { + this.child.on('close', (exitCode) => { this.buildView.buildFinished(0 === exitCode); if (0 === exitCode) { GoogleAnalytics.sendEvent('build', 'succeeded'); - this.finishedTimer = setTimeout(function() { + this.finishedTimer = setTimeout(() => { this.buildView.detach(); - }.bind(this), 1000); + }, 1000); } else { var t = this.targets[this.activeTarget]; this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); @@ -375,11 +375,11 @@ module.exports = { GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; - }.bind(this)); + }); this.buildView.buildStarted(); this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ') + '\n'); - }.bind(this)).catch(function (err) { + }).catch(function (err) { if (err instanceof BuildError) { if (source === 'save') { // If there is no eligible build tool, and cause of build was a save, stay quiet. @@ -397,12 +397,12 @@ module.exports = { abort: function(cb) { this.child.removeAllListeners('close'); - this.child.on('close', function() { + this.child.on('close', () => { this.child = null; if (cb) { cb(); } - }.bind(this)); + }); try { kill(this.child.pid); @@ -416,10 +416,10 @@ module.exports = { build: function(source, event) { clearTimeout(this.finishedTimer); - this.doSaveConfirm(this.unsavedTextEditors(), function() { + this.doSaveConfirm(this.unsavedTextEditors(), () => { var next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); this.child ? this.abort(next) : next(); - }.bind(this)); + }); }, doSaveConfirm: function(modifiedTextEditors, continuecb, cancelcb) { diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 8e61579a..ae02218d 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -98,14 +98,14 @@ module.exports = (function () { } regex = (regex instanceof Array) ? regex : [ regex ]; - this.regex = _.compact(regex.map(function(r) { + this.regex = _.compact(regex.map((r) => { try { return XRegExp(r); } catch (err) { this.emit('error', 'Error parsing regex. ' + err.message); return null; } - }.bind(this))); + })); this.cwd = cwd; this.output = output; diff --git a/lib/targets-view.js b/lib/targets-view.js index 9dcad24d..ccdc5320 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -56,9 +56,9 @@ module.exports = (function() { }; TargetsView.prototype.awaitSelection = function () { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { this.resolveFunction = resolve; - }.bind(this)); + }); }; TargetsView.prototype.confirmed = function(target) { From db17fb53581ff7a50b41dd15d4da0cccf6b6a511 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 11 Oct 2015 17:33:34 +0200 Subject: [PATCH 208/495] removed old code --- lib/build-view.js | 5 ----- lib/build.js | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 52f925a6..69382a8c 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -267,10 +267,5 @@ module.exports = (function() { } }; - BuildView.prototype.getOutput = function() { - this.append(new Buffer(0), true); - return this.output.text(); - }; - return BuildView; })(); diff --git a/lib/build.js b/lib/build.js index 6e314831..28a7038b 100644 --- a/lib/build.js +++ b/lib/build.js @@ -367,7 +367,7 @@ module.exports = { this.child.on('close', function(exitCode) { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.getOutput()); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.text()); var success = 0 === exitCode && !this.errorMatcher.hasMatch(); this.buildView.buildFinished(success); From 7c3f75665cd5bd74dfaf6acb430f1d6d5300f257 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 11 Oct 2015 23:43:42 +0200 Subject: [PATCH 209/495] buildview -> buildview.output --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 559f6132..ae155adf 100644 --- a/lib/build.js +++ b/lib/build.js @@ -361,7 +361,7 @@ module.exports = { this.child.on('close', (exitCode) => { var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.text()); + this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); var success = 0 === exitCode && !this.errorMatcher.hasMatch(); this.buildView.buildFinished(success); From 3a37935fac91ec14ef6defe218d9004f7e9b60ad Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Sun, 11 Oct 2015 23:51:46 +0200 Subject: [PATCH 210/495] added test case --- spec/build-spec.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/build-spec.js b/spec/build-spec.js index 89e9e4ee..38b830ba 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -72,6 +72,21 @@ describe('Build', function() { }); }); + it('should fail build, if errors are matched', function() { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo __ERROR__ && exit 0', + errorMatch: 'ERROR' + })); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + }); + it('should cancel build when stopping it, and remove when stopping again', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); From 1de4a5d045042295be9ecd4cbc6aba030ba07d1e Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Mon, 12 Oct 2015 23:44:04 +0200 Subject: [PATCH 211/495] removed child listeners before kill --- lib/build.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/build.js b/lib/build.js index ae155adf..e9293095 100644 --- a/lib/build.js +++ b/lib/build.js @@ -149,6 +149,7 @@ module.exports = { tool.off.apply(tool.ctx, [ 'refresh' ]); }); if (this.child) { + this.child.removeAllListeners(); kill(this.child.pid, 'SIGKILL'); } clearTimeout(this.finishedTimer); From d9ce4b2a7d2a3876accb5ab6a39a8780a3fb2745 Mon Sep 17 00:00:00 2001 From: Mackie Loeffel Date: Wed, 14 Oct 2015 19:23:04 +0200 Subject: [PATCH 212/495] added this.child = null --- lib/build.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/build.js b/lib/build.js index e9293095..66831042 100644 --- a/lib/build.js +++ b/lib/build.js @@ -151,6 +151,7 @@ module.exports = { if (this.child) { this.child.removeAllListeners(); kill(this.child.pid, 'SIGKILL'); + this.child = null; } clearTimeout(this.finishedTimer); }, From 1385891281d8ff48cc9ce851edd42fa2a08d94cf Mon Sep 17 00:00:00 2001 From: Koen Lageveen Date: Tue, 20 Oct 2015 19:15:27 +0200 Subject: [PATCH 213/495] better default font and match editor font --- lib/build-view.js | 6 ++++++ styles/build.less | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 2d4c84b5..f59f45f1 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -28,6 +28,7 @@ module.exports = (function() { atom.config.observe('build.panelOrientation', this.orientationFromConfig.bind(this)); atom.config.observe('build.monocleHeight', this.sizeFromConfig.bind(this)); atom.config.observe('build.minimizedHeight', this.sizeFromConfig.bind(this)); + atom.config.observe('editor.fontFamily', this.fontFromConfig.bind(this)); atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this)); } @@ -75,6 +76,7 @@ module.exports = (function() { let orientation = atom.config.get('build.panelOrientation') || 'Bottom'; this.panel = addfn[orientation].call(atom.workspace, { item: this }); this.sizeFromConfig(); + this.fontFromConfig(); }; BuildView.prototype.detach = function(force) { @@ -96,6 +98,10 @@ module.exports = (function() { this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight')); }; + BuildView.prototype.fontFromConfig = function() { + this.output.css("font-family", atom.config.get('editor.fontFamily')); + }; + BuildView.prototype.visibleFromConfig = function(val) { switch (val) { case 'Toggle': diff --git a/styles/build.less b/styles/build.less index 7b267720..1cb5a11e 100644 --- a/styles/build.less +++ b/styles/build.less @@ -41,7 +41,7 @@ overflow: auto; word-wrap: break-word; white-space: pre-wrap; - font-family: monospace; + font-family: 'Menlo', 'Consolas', 'DejaVu Sans Mono', monospace; } .status { From 4ed78340d04c5ee89437b9bdb6037b76be9a37cd Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 22 Oct 2015 19:51:18 +0200 Subject: [PATCH 214/495] BuildView: Fix code style --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index f59f45f1..460d01a0 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -99,7 +99,7 @@ module.exports = (function() { }; BuildView.prototype.fontFromConfig = function() { - this.output.css("font-family", atom.config.get('editor.fontFamily')); + this.output.css('font-family', atom.config.get('editor.fontFamily')); }; BuildView.prototype.visibleFromConfig = function(val) { From eef9c98518b751ceb56c46421c0759d22dc43a2e Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 22 Oct 2015 19:53:49 +0200 Subject: [PATCH 215/495] Prepare 0.48.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 39c26b7e..7e5402a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.47.0", + "version": "0.48.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From ad43b9d4d96a2f3bf43fc9ba63474dc43bafb663 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 28 Oct 2015 12:13:54 +0100 Subject: [PATCH 216/495] CSS: Same font for all text --- styles/build.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/build.less b/styles/build.less index 1cb5a11e..70eb1061 100644 --- a/styles/build.less +++ b/styles/build.less @@ -4,6 +4,7 @@ .build { height: 100%; + font-family: 'Menlo', 'Consolas', 'DejaVu Sans Mono', monospace; .title { transition: background-color 0.2s ease-in; @@ -41,7 +42,6 @@ overflow: auto; word-wrap: break-word; white-space: pre-wrap; - font-family: 'Menlo', 'Consolas', 'DejaVu Sans Mono', monospace; } .status { From a32f3551e5f40349bd2388043ee89d5702fbb493 Mon Sep 17 00:00:00 2001 From: Jan Niklas Hasse Date: Thu, 29 Oct 2015 12:29:45 +0100 Subject: [PATCH 217/495] Add new keybindings --- README.md | 14 +++++++------- keymaps/build.json | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 49cc0a6d..48a767ec 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ Automatically build your project inside your new favorite editor, Atom. - * `cmd-alt-b` / `ctrl-alt-b` builds your project. - * `cmd-alt-g` / `ctrl-alt-g` cycles through causes of build error. See [Error Matching](#error-match). - * `cmd-alt-h` / `ctrl-alt-h` goes to the first build error. See [Error Matching](#error-match). - * `cmd-alt-v` / `ctrl-alt-v` Toggles the build panel. - * `cmd-alt-t` / `ctrl-alt-t` Displays the available build targets. + * `cmd-alt-b` / `ctrl-alt-b` / `f9` builds your project. + * `cmd-alt-g` / `ctrl-alt-g` / `f4` cycles through causes of build error. See [Error Matching](#error-match). + * `cmd-alt-h` / `ctrl-alt-h` / `shift-f4` goes to the first build error. See [Error Matching](#error-match). + * `cmd-alt-v` / `ctrl-alt-v` / `f8` Toggles the build panel. + * `cmd-alt-t` / `ctrl-alt-t` / `f7` Displays the available build targets. * `escape` terminates build / closes the build window. ![work work](https://noseglid.github.io/atom-build.gif) @@ -93,7 +93,7 @@ correct file, row and column of the error. For instance: ``` Would be matched with the regular expression: `\n(?[\\/0-9a-zA-Z\\._]+):(?\\d+):(?\\d+)`. -After the build has failed, pressing `cmd-alt-g` (OS X) or `ctrl-alt-g` (Linux/Windows), `a.c` would be +After the build has failed, pressing `cmd-alt-g` (OS X) or `f4` (Linux/Windows), `a.c` would be opened and the cursor would be placed at row 4, column 26. Note the syntax for match groups. This is from the [XRegExp](http://xregexp.com/) package @@ -115,7 +115,7 @@ If your build outputs multiple errors, all will be matched. Press `cmd-alt-g` (O to cycle through the errors (in the order they appear, first on stderr then on stdout). Often, the first error is the most interesting since other errors tend to be secondary faults caused by that first one. -To jump to the first error you can use `cmd-alt-h` (OS X) or `ctrl-alt-h` (Linux/Windows) at any point to go to the first error. +To jump to the first error you can use `cmd-alt-h` (OS X) or `shift-f4` (Linux/Windows) at any point to go to the first error. ## Service API (for package developers) diff --git a/keymaps/build.json b/keymaps/build.json index 6098cac1..5a3e6fc5 100644 --- a/keymaps/build.json +++ b/keymaps/build.json @@ -13,6 +13,13 @@ "ctrl-alt-h": "build:error-match-first", "ctrl-alt-t": "build:select-active-target" }, + "atom-workspace, atom-text-editor": { + "f9": "build:trigger", + "f8": "build:toggle-panel", + "f4": "build:error-match", + "shift-f4": "build:error-match-first", + "f7": "build:select-active-target" + }, ".build": { "escape": "build:stop" }, From 1b5398764ec199ce7263499b804ea912fbb0f973 Mon Sep 17 00:00:00 2001 From: nsf Date: Wed, 4 Nov 2015 03:04:15 +0500 Subject: [PATCH 218/495] Use regexps with '/g' modifier to replace all matches of built-in vars. --- lib/build.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/build.js b/lib/build.js index 66831042..5f739b5e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -283,10 +283,10 @@ module.exports = { if (editor && 'untitled' !== editor.getTitle()) { var activeFile = fs.realpathSync(editor.getPath()); var activeFilePath = path.dirname(activeFile); - value = value.replace('{FILE_ACTIVE}', activeFile); - value = value.replace('{FILE_ACTIVE_PATH}', activeFilePath); - value = value.replace('{FILE_ACTIVE_NAME}', path.basename(activeFile)); - value = value.replace('{FILE_ACTIVE_NAME_BASE}', path.basename(activeFile, path.extname(activeFile))); + value = value.replace(/{FILE_ACTIVE}/g, activeFile); + value = value.replace(/{FILE_ACTIVE_PATH}/g, activeFilePath); + value = value.replace(/{FILE_ACTIVE_NAME}/g, path.basename(activeFile)); + value = value.replace(/{FILE_ACTIVE_NAME_BASE}/g, path.basename(activeFile, path.extname(activeFile))); } var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { try { @@ -297,9 +297,9 @@ module.exports = { return activeFilePath && activeFilePath.startsWith(projectPath); }) || projectPaths[0]; - value = value.replace('{PROJECT_PATH}', projectPath); + value = value.replace(/{PROJECT_PATH}/g, projectPath); if (atom.project.getRepositories[0]) { - value = value.replace('{REPO_BRANCH_SHORT}', atom.project.getRepositories()[0].getShortHead()); + value = value.replace(/{REPO_BRANCH_SHORT}/g, atom.project.getRepositories()[0].getShortHead()); } return value; From c80fc574e81d6d5f54dbffddc7b7134f84b4aec5 Mon Sep 17 00:00:00 2001 From: Koen Lageveen Date: Wed, 4 Nov 2015 10:20:31 +0100 Subject: [PATCH 219/495] improve layout in sidebar mode --- styles/build.less | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/styles/build.less b/styles/build.less index 70eb1061..708a37fe 100644 --- a/styles/build.less +++ b/styles/build.less @@ -13,7 +13,7 @@ .build-timer { display: inline-block; width: 5em; - margin-right: 10px; + margin-right: @component-padding; } .title.error { @@ -37,7 +37,7 @@ .output { transition: 0.5s ease-in-out; transition-property: width, height; - padding: 10px 0 @status-panel-height 10px; + padding: @component-padding 0 @status-panel-height @component-padding; min-height: 100px; overflow: auto; word-wrap: break-word; @@ -63,7 +63,7 @@ .btn-container { .btn { float: right; - margin: 10px 10px 0 0; + margin: @component-padding @component-padding 0 0; color: @text-color-info; } @@ -75,3 +75,20 @@ clear: both; } } + +.panel-left .build, +.panel-right .build { + .btn-container { + float: none !important; + .new-row { + clear: none; + } + .btn:last-child { + margin-left: @component-padding; + } + } + .output { + min-width: 200px; + padding-right: @component-padding; + } +} From d6e9c78a334f94f882c2c4810dd7d7e39436926e Mon Sep 17 00:00:00 2001 From: James Ward Date: Wed, 4 Nov 2015 15:41:51 -0700 Subject: [PATCH 220/495] Add build-sbt --- build-tools.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-tools.md b/build-tools.md index 97cab24c..cbb39f2f 100644 --- a/build-tools.md +++ b/build-tools.md @@ -12,6 +12,7 @@ | [Markdown][14] | [build-markdown][15] | | [Gradle][16] | [build-gradle][17] | | [JPM][18] | [build-jpm][19] | +| [sbt][20] | [build-sbt][21] | Have you created a build plugin and want it displayed here? Create a pull request modifying this list. @@ -35,3 +36,5 @@ Create a pull request modifying this list. [17]: https://atom.io/packages/build-gradle [18]: https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/jpm [19]: https://atom.io/packages/build-jpm +[20]: https://scala-sbt.org +[21]: https://atom.io/packages/build-sbt From c301f9cae5b12b874914fddb77c37026de33f36c Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 18 Nov 2015 22:18:10 +0100 Subject: [PATCH 221/495] Better support for multiple root projects Targets (as well as active target) are now cached on a per project basis. This has several implications: * Targets will only be reloaded when root project paths are added/removed or when triggered manually. This means that selecting active target wont implicitly refresh the cache. This improves usability when switching between active targets. * Working with multiple project roots is now possible without re-selecting active targets. Fixes #179 --- lib/atom-build.js | 16 +- lib/build.js | 303 +++++++++++++++++---------------- package.json | 2 +- spec/build-confirm-spec.js | 60 ++++--- spec/build-error-match-spec.js | 78 ++++++--- spec/build-keymap-spec.js | 24 +-- spec/build-spec.js | 120 ++++++++++--- spec/build-targets-spec.js | 21 ++- spec/build-view-spec.js | 50 ++++-- spec/build-visible-spec.js | 20 ++- 10 files changed, 437 insertions(+), 257 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index 6828f3c7..2cd37fe3 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -55,27 +55,21 @@ module.exports.settings = function (cwd) { return config; }; -let fileWatchers = []; module.exports.on = function (ev, cb) { + this.fileWatchers = this.fileWatchers || []; if ('refresh' !== ev || !this.files) { return; } - fileWatchers.forEach(watcher => { - watcher.close(); - }); - - fileWatchers = this.files.map(file => { - return fs.watch(file, cb); - }); + this.fileWatchers.push.apply(this.fileWatchers, this.files.map(file => fs.watch(file, cb))); }; module.exports.off = function (ev) { + this.fileWatchers = this.fileWatchers || []; if ('refresh' !== ev) { return; } - fileWatchers.forEach(watcher => { - watcher.close(); - }); + this.fileWatchers.forEach(watcher => watcher.close()); + this.fileWatchers = []; }; diff --git a/lib/build.js b/lib/build.js index 5f739b5e..902b0392 100644 --- a/lib/build.js +++ b/lib/build.js @@ -98,14 +98,15 @@ module.exports = { this.buildView = new BuildView(); - this.cmd = {}; this.targets = {}; - this.activeTarget = null; - this.match = []; + this.activeTarget = {}; + this.targetsLoading = {}; + this.stdout = new Buffer(0); this.stderr = new Buffer(0); this.errorMatcher = new ErrorMatcher(); + atom.commands.add('atom-workspace', 'build:refresh-targets', () => this.refreshTargets()); atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this, 'trigger')); atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this)); @@ -141,12 +142,21 @@ module.exports = { this.buildView.link(text, id, callback); }); - this.refreshTargets().catch(function(e) {}); + atom.packages.onDidActivateInitialPackages(() => this.refreshTargets()); + + let projectPaths = atom.project.getPaths(); + atom.project.onDidChangePaths(() => { + let addedPaths = atom.project.getPaths().filter(el => projectPaths.indexOf(el) === -1); + this.refreshTargets(addedPaths); + projectPaths = atom.project.getPaths(); + }); }, deactivate: function() { tools.forEach(tool => { - tool.off.apply(tool.ctx, [ 'refresh' ]); + if (tool.off) { + _.forEach(tool.ctx, (ctx, path) => tool.off.apply(ctx, [ 'refresh' ])); + } }); if (this.child) { this.child.removeAllListeners(); @@ -167,7 +177,7 @@ module.exports = { return atom.project.getPaths()[0]; } else { /* otherwise, build the one in the root of the active editor */ - return _.find(atom.project.getPaths(), function (path) { + return atom.project.getPaths().sort((a, b) => (b.length - a.length)).find(path => { var realpath = fs.realpathSync(path); return textEditor.getPath().substr(0, realpath.length) === realpath; }); @@ -180,101 +190,115 @@ module.exports = { args: [], cwd: path, sh: true, - errorMatch: '' + errorMatch: '', + dispose: Function.prototype }; }, - refreshTargets: function() { - var path = this.activePath(); - var prioritizedTarget; - - return Promise.resolve(tools) - .then(function () { - if (!path) { - throw new BuildError('No active project', 'No project is active, don\'t know what to build...'); + refreshTargets: function(refreshPaths) { + refreshPaths = refreshPaths || atom.project.getPaths(); + + let pathPromise = refreshPaths.map((path) => { + this.targetsLoading[path] = true; + this.targets[path] = this.targets[path] || []; + let settingsPromise = tools.filter((tool) => { + tool.ctx = tool.ctx || []; + tool.ctx[path] = tool.ctx[path] || {}; + return tool.isEligable.apply(tool.ctx[path], [ path ]); + }).map((tool) => { + GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); + + if (tool.on) { + tool.off.apply(tool.ctx[path], [ 'refresh' ]); + tool.on.apply(tool.ctx[path], [ 'refresh', this.refreshTargets.bind(this, [ path ]) ]); } - return _.filter(tools, function (tool) { - tool.ctx = {}; - return tool.isEligable.apply(tool.ctx, [ path ]); - }); - }) - .then(tools => { - return Promise.all(_.map(tools, tool => { - GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); - - if (tool.on) { - tool.off.apply(tool.ctx, [ 'refresh' ]); - tool.on.apply(tool.ctx, [ 'refresh', this.refreshTargets.bind(this) ]); + return Promise.resolve().then(() => { + return tool.settings.apply(tool.ctx[path], [ path ]); + }).catch(function (err) { + if (err instanceof SyntaxError) { + atom.notifications.addError('Invalid build file.', { + detail: 'You have a syntax error in your build file: ' + err.message, + dismissable: true + }); + } else { + atom.notifications.addError('Ooops. Something went wrong.', { + detail: err.message + (err.stack ? '\n' + err.stack : ''), + dismissable: true + }); } + }); + }); - return tool.settings.apply(tool.ctx, [ path ]); - })); - }) - .then(_.flatten) - .then((settings) => { - if (0 === _.size(settings)) { - throw new BuildError('No eligible build tool.', 'No tool can provide any build configurations.'); - } + return Promise.all(settingsPromise).then((settings) => { + settings = [].concat.apply([], settings).filter(Boolean).map(setting => + _.defaults(setting, this.cmdDefaults(path)) + ); - prioritizedTarget = settings[0].name; - return _.map(settings, (setting) => { - return [ setting.name, _.defaults(setting, this.cmdDefaults(path)) ]; - }); - }) - .then(_.zipObject) - .then((targets) => { - if (_.isNull(this.activeTarget) || _.isUndefined(targets[this.activeTarget])) { + if (_.isNull(this.activeTarget[path]) || !settings.find(s => s.name === this.activeTarget[path])) { /* Active target has been removed or not set. Set it to the highest prio target */ - this.activeTarget = prioritizedTarget; + this.activeTarget[path] = settings[0] ? settings[0].name : undefined; } - _.forEach(this.targets, function (target) { - target.dispose(); // Gets rid of keymaps and commands registered - }); + this.targets[path].forEach(target => target.dispose()); - _.forEach(targets, (target, targetName) => { - if (!target.keymap) { - target.dispose = _.noop; + settings.forEach((setting, index) => { + if (!setting.keymap) { return; } - GoogleAnalytics.sendEvent('keymap', 'registered', target.keymap); - var commandName = 'build:trigger:' + targetName; + GoogleAnalytics.sendEvent('keymap', 'registered', setting.keymap); + var commandName = 'build:trigger:' + setting.name; var keymapSpec = { 'atom-workspace': {} }; - keymapSpec['atom-workspace'][target.keymap] = commandName; - var keymapDispose = atom.keymaps.add(targetName, keymapSpec); + keymapSpec['atom-workspace'][setting.keymap] = commandName; + var keymapDispose = atom.keymaps.add(setting.name, keymapSpec); var commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); - target.dispose = function () { + settings[index].dispose = function () { keymapDispose.dispose(); commandDispose.dispose(); }; }); - return (this.targets = targets); + this.targets[path] = settings; + this.targetsLoading[path] = false; }); + }); + + Promise.all(pathPromise).then((entries) => { + if (entries.length === 0) { + return; + } + + let rows = refreshPaths.map(path => `${this.targets[path].length} targets at: ${path}`); + atom.notifications.addInfo('Build targets parsed.', { + detail: rows.join('\n') + }); + }); }, selectActiveTarget: function() { - var targetsView = new TargetsView(); - targetsView.setLoading('Loading project build targets...\u2026'); + let path = this.activePath(); + let targets = this.targets[path]; + let targetsView = new TargetsView(); - this.refreshTargets().then((targets) => { - targetsView.setActiveTarget(this.activeTarget); - targetsView.setItems(_.keys(targets)); - return targetsView.awaitSelection(); - }).then((newTarget) => { - this.activeTarget = newTarget; + if (this.targetsLoading[path]) { + return targetsView.setLoading('Loading project build targets\u2026'); + } - var workspaceElement = atom.views.getView(atom.workspace); + targetsView.setActiveTarget(this.activeTarget[path]); + targetsView.setItems((targets || []).map(target => target.name)); + targetsView.awaitSelection().then((newTarget) => { + this.activeTarget[path] = newTarget; + + let workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); }).catch(function (err) { targetsView.setError(err.message); }); }, - replace: function(value) { - var env = _.extend(_.clone(process.env), this.cmd.env); + replace: function(value, targetEnv) { + var env = _.extend(_.clone(process.env), targetEnv); value = value.replace(/\$(\w+)/g, function(match, name) { return name in env ? env[name] : match; }); @@ -306,97 +330,90 @@ module.exports = { }, startNewBuild: function(source, targetName) { - this.cmd = {}; - this.match = []; - - Promise.resolve() - .then(() => { - return (this.activeTarget) ? this.targets : this.refreshTargets(); - }) - .then((targets) => { - this.cmd = targets[targetName ? targetName : this.activeTarget]; - GoogleAnalytics.sendEvent('build', 'triggered'); - - if (!this.cmd.exec) { - atom.notifications.addError('Invalid build file.', { detail: 'No executable command specified.' }); - return; - } + let path = this.activePath(); - var env = _.extend(_.clone(process.env), this.cmd.env); - _.each(env, (value, key, list) => { - list[key] = this.replace(value); - }); + Promise.resolve(this.targets[path]).then(targets => { + if (!targets) { + throw new BuildError('No eligible build target.', 'No configuration to build this project exists.'); + } + + let target = targets.find(target => (targetName) ? target.name === targetName : target.name === this.activeTarget[path]); + GoogleAnalytics.sendEvent('build', 'triggered'); - var args = _.map(this.cmd.args, this.replace.bind(this)); + if (!target.exec) { + throw new BuildError('Inavlid build file.', 'No executable command specified.'); + } - this.cmd.exec = this.replace(this.cmd.exec); + var env = _.extend(_.clone(process.env), target.env); + _.each(env, (value, key, list) => { + list[key] = this.replace(value, target.env); + }); - this.child = child_process.spawn( - this.cmd.sh ? '/bin/sh' : this.cmd.exec, - this.cmd.sh ? [ '-c', [ this.cmd.exec ].concat(args).join(' ') ] : args, - { cwd: this.replace(this.cmd.cwd), env: env } - ); + let exec = this.replace(target.exec, target.env); + var args = _.map(target.args, (arg) => this.replace(arg, target.env)); + let cwd = this.replace(target.cwd, target.env); - this.stdout = new Buffer(0); - this.child.stdout.on('data', (buffer) => { - this.stdout = Buffer.concat([ this.stdout, buffer ]); - this.buildView.append(buffer); - }); + this.child = child_process.spawn( + target.sh ? '/bin/sh' : exec, + target.sh ? [ '-c', [ exec ].concat(args).join(' ') ] : args, + { cwd: cwd, env: env } + ); - this.stderr = new Buffer(0); - this.child.stderr.on('data', (buffer) => { - this.stderr = Buffer.concat([ this.stderr, buffer ]); - this.buildView.append(buffer); - }); + this.stdout = new Buffer(0); + this.child.stdout.on('data', (buffer) => { + this.stdout = Buffer.concat([ this.stdout, buffer ]); + this.buildView.append(buffer); + }); - this.child.on('error', (err) => { - this.buildView.append((this.cmd.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + this.cmd.exec + '\n'); + this.stderr = new Buffer(0); + this.child.stderr.on('data', (buffer) => { + this.stderr = Buffer.concat([ this.stderr, buffer ]); + this.buildView.append(buffer); + }); - if (/\s/.test(this.cmd.exec) && !this.cmd.sh) { - this.buildView.append('`cmd` cannot contain space. Use `args` for arguments.\n'); - } + this.child.on('error', (err) => { + this.buildView.append((target.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + exec + '\n'); - if ('ENOENT' === err.code) { - this.buildView.append('Make sure `cmd` and `cwd` exists and have correct access permissions.'); - } - }); + if (/\s/.test(exec) && !target.sh) { + this.buildView.append('`cmd` cannot contain space. Use `args` for arguments.\n'); + } - this.child.on('close', (exitCode) => { - var t = this.targets[this.activeTarget]; - this.errorMatcher.set(t.errorMatch, this.replace(t.cwd), this.buildView.output.text()); - - var success = 0 === exitCode && !this.errorMatcher.hasMatch(); - this.buildView.buildFinished(success); - if (success) { - GoogleAnalytics.sendEvent('build', 'succeeded'); - this.finishedTimer = setTimeout(() => { - this.buildView.detach(); - }, 1000); - } else { - if (atom.config.get('build.scrollOnError')) { - this.errorMatcher.matchFirst(); - } - GoogleAnalytics.sendEvent('build', 'failed'); - } - this.child = null; - }); + if ('ENOENT' === err.code) { + this.buildView.append('Make sure `cmd` and `cwd` exists and have correct access permissions.'); + } + }); - this.buildView.buildStarted(); - this.buildView.append((this.cmd.sh ? 'Executing with sh: ' : 'Executing: ') + this.cmd.exec + [ ' ' ].concat(args).join(' ') + '\n'); - }).catch(function (err) { - if (err instanceof BuildError) { - if (source === 'save') { - // If there is no eligible build tool, and cause of build was a save, stay quiet. - return; - } + this.child.on('close', (exitCode) => { + this.errorMatcher.set(target.errorMatch, cwd, this.buildView.output.text()); - atom.notifications.addWarning(err.name, { detail: err.message }); - } else if (err instanceof SyntaxError) { - atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + err.message }); + var success = 0 === exitCode && !this.errorMatcher.hasMatch(); + this.buildView.buildFinished(success); + if (success) { + GoogleAnalytics.sendEvent('build', 'succeeded'); + this.finishedTimer = setTimeout(() => { + this.buildView.detach(); + }, 1000); } else { - atom.notifications.addError('Ooops. Something went wrong.', { detail: err.message + (err.stack ? '\n' + err.stack : '') }); + if (atom.config.get('build.scrollOnError')) { + this.errorMatcher.matchFirst(); + } + GoogleAnalytics.sendEvent('build', 'failed'); } + this.child = null; }); + + this.buildView.buildStarted(); + this.buildView.append((target.sh ? 'Executing with sh: ' : 'Executing: ') + exec + [ ' ' ].concat(args).join(' ') + '\n'); + }).catch(function (err) { + if (err instanceof BuildError) { + if (source === 'save') { + // If there is no eligible build tool, and cause of build was a save, stay quiet. + return; + } + + atom.notifications.addWarning(err.name, { detail: err.message }); + } + }); }, abort: function(cb) { diff --git a/package.json b/package.json index 7e5402a8..7c067f87 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "devDependencies": { "fs-extra": "^0.23.0", "temp": "^0.8.1", - "atom-build-spec-helpers": "^0.1.0", + "atom-build-spec-helpers": "^0.2.0", "jshint": "^2.5.11", "jscs": "^1.9.0" }, diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 1549c7b4..7dbc8e0f 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -4,6 +4,7 @@ var _ = require('lodash'); var fs = require('fs-extra'); var temp = require('temp'); +var specHelpers = require('atom-build-spec-helpers'); describe('Confirm', function() { var directory = null; @@ -103,11 +104,11 @@ describe('Confirm', function() { })); waitsForPromise(function() { - return atom.workspace.open('.atom-build.json'); - }); - - waitsForPromise(function() { - return atom.workspace.open(); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('.atom-build.json'), + atom.workspace.open() + ]); }); runs(function() { @@ -132,29 +133,27 @@ describe('Confirm', function() { it('should save and build when selecting save and build', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + cmd: 'cat catme' })); waitsForPromise(function() { - return atom.workspace.open('.atom-build.json'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('catme') + ]); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.setText(JSON.stringify({ - cmd: 'echo kansas' - })); + editor.setText('kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { - return workspaceElement.querySelector(':focus'); - }); + waitsFor(() => workspaceElement.querySelector(':focus')); - runs(function() { - workspaceElement.querySelector(':focus').click(); - }); + runs(() => workspaceElement.querySelector(':focus').click()); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -172,19 +171,21 @@ describe('Confirm', function() { it('should build but not save when opting so', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + cmd: 'cat catme' })); waitsForPromise(function() { - return atom.workspace.open('.atom-build.json'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('catme') + ]); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.setText(JSON.stringify({ - cmd: 'echo kansas' - })); + editor.setText('catme'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -212,19 +213,21 @@ describe('Confirm', function() { it('should do nothing when cancelling', function() { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' + cmd: 'cat catme' })); waitsForPromise(function() { - return atom.workspace.open('.atom-build.json'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('catme') + ]); }); runs(function() { var editor = atom.workspace.getActiveTextEditor(); - editor.setText(JSON.stringify({ - cmd: 'echo kansas' - })); + editor.setText('kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -255,7 +258,10 @@ describe('Confirm', function() { })); waitsForPromise(function() { - return atom.workspace.open('.atom-build.json'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('.atom-build.json') + ]); }); runs(function() { diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 27fcc1ee..a32b23bb 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -2,6 +2,7 @@ var fs = require('fs-extra'); var temp = require('temp'); +var specHelpers = require('atom-build-spec-helpers'); describe('Error Match', function() { var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; @@ -52,7 +53,9 @@ describe('Error Match', function() { errorMatch: '(invalidRegex' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -75,7 +78,10 @@ describe('Error Match', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -103,7 +109,10 @@ describe('Error Match', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNoFileBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -129,7 +138,10 @@ describe('Error Match', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNLCAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -154,7 +166,10 @@ describe('Error Match', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -216,7 +231,10 @@ describe('Error Match', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiFirstAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -275,12 +293,14 @@ describe('Error Match', function() { }); it('should open the the file even if tool gives absolute path', function () { - var atomBuild = { + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo __' + directory + '.atom-build.json__ && return 1', errorMatch: '__(?.+)__' - }; - fs.writeFileSync(directory + '.atom-build.json', JSON.stringify(atomBuild)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + })); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -308,7 +328,10 @@ describe('Error Match', function() { errorMatch: '__(?.+)__' }; fs.writeFileSync(directory + '.atom-build.json', JSON.stringify(atomBuild)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function () { return workspaceElement.querySelector('.build .title') && @@ -351,7 +374,9 @@ describe('Error Match', function() { fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -374,7 +399,10 @@ describe('Error Match', function() { it('should scroll the build panel to the text of the error', function () { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -386,28 +414,32 @@ describe('Error Match', function() { }); waits(100); + let firstScrollTop; runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(168); + expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); runs(function() { /* Should wrap around to first match */ - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); }); }); it('match-first should scroll the build panel', function () { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -419,20 +451,21 @@ describe('Error Match', function() { }); waits(100); + let firstScrollTop; runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(168); + expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); waits(100); runs(function() { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(101); + expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); }); }); @@ -440,7 +473,10 @@ describe('Error Match', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiMatcherAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index 0970b2cb..bd436f18 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -50,9 +50,9 @@ describe('Keymap', function() { } })); - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function () { return workspaceElement.querySelector('.build .title') && @@ -95,9 +95,9 @@ describe('Keymap', function() { } })); - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function () { return workspaceElement.querySelector('.build .title') && @@ -158,9 +158,9 @@ describe('Keymap', function() { } })); - runs(function () { - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function () { return workspaceElement.querySelector('.build .title') && @@ -200,7 +200,11 @@ describe('Keymap', function() { })); }); - waits(300); // Custom file is reloaded automatically + waitsForPromise(() => specHelpers.awaitTargets()); + + waitsFor(function() { + return !workspaceElement.querySelector('.build .title'); + }); runs(function () { specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); diff --git a/spec/build-spec.js b/spec/build-spec.js index 38b830ba..18ef1254 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -59,7 +59,10 @@ describe('Build', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Very bad... && exit 1' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -79,7 +82,10 @@ describe('Build', function() { cmd: 'echo __ERROR__ && exit 0', errorMatch: 'ERROR' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -93,7 +99,10 @@ describe('Build', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo "Building, this will take some time..." && sleep 30 && echo "Done!"' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); // Let build run for one second before we terminate it waits(1000); @@ -141,7 +150,10 @@ describe('Build', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo hello world' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title').classList.contains('success'); @@ -166,7 +178,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -183,7 +198,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shellAtomBuildfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -200,7 +218,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shTrueAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -217,7 +238,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shFalseAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -234,7 +258,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shDefaultAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -251,7 +278,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(syntaxErrorAtomBuildFile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return atom.notifications.getNotifications().length > 0; @@ -272,7 +302,10 @@ describe('Build', function() { cmd: 'echo first' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); + waitsFor(function () { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); @@ -318,12 +351,13 @@ describe('Build', function() { fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(replaceAtomBuildFile)); waitsForPromise(function() { - return atom.workspace.open('.atom-build.json'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('.atom-build.json') + ]); }); - runs(function() { - atom.commands.dispatch(workspaceElement, 'build:trigger'); - }); + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -353,7 +387,10 @@ describe('Build', function() { })); waitsForPromise(function() { - return atom.workspace.open('dummy'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('dummy') + ]); }); runs(function() { @@ -380,7 +417,10 @@ describe('Build', function() { }); waitsForPromise(function() { - return atom.workspace.open('dummy'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open('dummy') + ]); }); runs(function() { @@ -417,11 +457,14 @@ describe('Build', function() { it('should run the second root if a file there is active', function () { var directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.addPath(directory2); - expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); + expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); waitsForPromise(function () { - return atom.workspace.open(directory2 + '/main.c'); + return Promise.all([ + specHelpers.refreshAwaitTargets(), + atom.workspace.open(directory2 + '/main.c'), + ]); }); runs(function() { @@ -439,6 +482,33 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); }); }); + + it('should scan new project roots when they are added', function () { + var directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); + + atom.project.addPath(directory2); + + waitsForPromise(() => Promise.all([ + atom.workspace.open(directory2 + '/main.c'), + specHelpers.awaitTargets() + ])); + + runs(() => { + atom.workspace.getActiveTextEditor().save(); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + }); + + waitsFor(function() { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(function() { + expect(workspaceElement.querySelector('.build')).toExist(); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); + }); + }); }); describe('when build panel is toggled and it is not visible', function() { @@ -456,7 +526,10 @@ describe('Build', function() { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build'); @@ -474,7 +547,10 @@ describe('Build', function() { var activeElement = document.activeElement; fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build'); @@ -499,7 +575,7 @@ describe('Build', function() { runs(function() { var notification = atom.notifications.getNotifications()[0]; expect(notification.getType()).toEqual('warning'); - expect(notification.getMessage()).toEqual('No eligible build tool.'); + expect(notification.getMessage()).toEqual('No eligible build target.'); }); }); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 7ae27c20..082ce4ee 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -43,9 +43,12 @@ describe('Target', function() { it('should list those targets in a SelectListView (from .atom-build.json)', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') + .then(() => specHelpers.refreshAwaitTargets()); }); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + runs(function () { atom.commands.dispatch(workspaceElement, 'build:select-active-target'); }); @@ -55,9 +58,7 @@ describe('Target', function() { }); runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), function (el) { - return el.textContent; - }); + var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), el => el.textContent); expect(targets).toEqual([ 'Custom: The default build', 'Custom: Some customized build' ]); }); }); @@ -65,7 +66,8 @@ describe('Target', function() { it('should mark the first target as active', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') + .then(() => specHelpers.refreshAwaitTargets()); }); runs(function () { @@ -86,7 +88,8 @@ describe('Target', function() { it('should run the selected build', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') + .then(() => specHelpers.refreshAwaitTargets()); }); runs(function () { @@ -114,7 +117,8 @@ describe('Target', function() { it('should run the default target if no selection has been made', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') + .then(() => specHelpers.refreshAwaitTargets()); }); runs(function () { @@ -134,7 +138,8 @@ describe('Target', function() { it('run the selected target if selection has changed, and subsequent build should run that target', function () { waitsForPromise(function () { var file = __dirname + '/fixture/.atom-build.targets.json'; - return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json'); + return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') + .then(() => specHelpers.refreshAwaitTargets()); }); runs(function () { diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 1518e6c6..fd11ac3e 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -50,7 +50,10 @@ describe('BuildView', function() { cmd: 'printf "\\033[31mHello\\e[0m World"' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); + waitsFor(function () { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); @@ -66,7 +69,10 @@ describe('BuildView', function() { cmd: 'printf "data without linebreak"' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); + waitsFor(function () { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); @@ -82,7 +88,10 @@ describe('BuildView', function() { cmd: 'node -e \'process.stdout.write("same"); setTimeout(function () { process.stdout.write(" line\\n") }, 200);\'' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); + waitsFor(function () { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); @@ -103,7 +112,10 @@ describe('BuildView', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo ""' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -124,7 +136,10 @@ describe('BuildView', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo "Building, this will take some time..." && sleep 30 && echo "Done!"' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); // Let build run for 1.2 second. This should set the timer at "at least" 1.2 // which is expected below. If this waits longer than 2000 ms, we're in trouble. @@ -148,7 +163,10 @@ describe('BuildView', function() { cmd: 'echo match1 match1 match1 && exit 1', errorMatch: 'match1' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -173,7 +191,10 @@ describe('BuildView', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo this will fail && exit 1', })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -194,7 +215,10 @@ describe('BuildView', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo this will fail && exit 1', })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -215,7 +239,10 @@ describe('BuildView', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo this will fail && exit 1', })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && @@ -236,7 +263,10 @@ describe('BuildView', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo this will fail && exit 1', })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waitsFor(function() { return workspaceElement.querySelector('.build .title') && diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index d43f1441..528f8a37 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -85,7 +85,10 @@ describe('Visible', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); /* Give it some reasonable time to show itself if there is a bug */ waits(200); @@ -124,7 +127,10 @@ describe('Visible', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); /* Give it some reasonable time to show itself if there is a bug */ waits(200); @@ -140,7 +146,10 @@ describe('Visible', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo "Very bad..." && exit 2' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); /* Give it some reasonable time to show itself if there is a bug */ waits(200); @@ -156,7 +165,10 @@ describe('Visible', function() { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); waits(200); // Let build finish. Since UI component is not visible yet, there's nothing to poll. From 6139d92e6aa98c5b1095fadfd9a36e525dc04e4a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 11:31:56 +0100 Subject: [PATCH 222/495] Prepare 0.49.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c067f87..cd855176 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.48.0", + "version": "0.49.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 01ee139e61dfdb09ccb8b447454866a0db38eb0a Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Wed, 11 Nov 2015 23:05:19 -0700 Subject: [PATCH 223/495] Use ECMA import statements. --- lib/atom-build.js | 8 ++++---- lib/build-view.js | 11 +++++------ lib/build.js | 24 ++++++++++++------------ lib/error-matcher.js | 14 +++++++------- lib/google-analytics.js | 4 ++-- lib/save-confirm-view.js | 4 ++-- lib/targets-view.js | 4 ++-- 7 files changed, 34 insertions(+), 35 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index 2cd37fe3..ddb59bdb 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -1,10 +1,10 @@ 'use babel'; 'use strict'; -var path = require('path'); -var fs = require('fs'); -var _ = require('lodash'); -var CSON = require('cson-parser'); +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; +import CSON from 'cson-parser'; module.exports.niceName = 'Custom file'; diff --git a/lib/build-view.js b/lib/build-view.js index 460d01a0..254cc3c5 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -1,12 +1,11 @@ 'use babel'; 'use strict'; -var _ = require('lodash'); -var View = require('atom-space-pen-views').View; -var $ = require('atom-space-pen-views').$; -var ansi_up = require('ansi_up'); -var cscompatability = require('./cscompatability'); -var GoogleAnalytics = require('./google-analytics'); +import _ from 'lodash'; +import {View, $} from 'atom-space-pen-views'; +import ansi_up from 'ansi_up'; +import cscompatability from './cscompatability'; +import GoogleAnalytics from './google-analytics'; module.exports = (function() { function BuildView() { diff --git a/lib/build.js b/lib/build.js index 902b0392..e1c2c85e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -1,18 +1,18 @@ 'use babel'; 'use strict'; -var child_process = require('child_process'); -var fs = require('fs'); -var path = require('path'); -var _ = require('lodash'); -var Disposable = require('atom').Disposable; -var kill = require('tree-kill'); - -var SaveConfirmView = require('./save-confirm-view'); -var TargetsView = require('./targets-view'); -var BuildView = require('./build-view'); -var GoogleAnalytics = require('./google-analytics'); -var ErrorMatcher = require('./error-matcher'); +import child_process from 'child_process'; +import fs from 'fs'; +import path from 'path'; +import _ from 'lodash'; +import {Disposable} from 'atom'; +import kill from 'tree-kill'; + +import SaveConfirmView from './save-confirm-view'; +import TargetsView from './targets-view'; +import BuildView from './build-view'; +import GoogleAnalytics from './google-analytics'; +import ErrorMatcher from './error-matcher'; var tools = [ require('./atom-build') ]; function BuildError(name, message) { diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 604d9a6e..cc675e2f 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -1,13 +1,13 @@ 'use babel'; 'use strict'; -var fs = require('fs'); -var path = require('path'); -var XRegExp = require('xregexp').XRegExp; -var GoogleAnalytics = require('./google-analytics'); -var EventEmitter = require('events').EventEmitter; -var util = require('util'); -var _ = require('lodash'); +import fs from 'fs'; +import path from 'path'; +import {XRegExp} from 'xregexp'; +import GoogleAnalytics from './google-analytics'; +import {EventEmitter} from 'events'; +import util from 'util'; +import _ from 'lodash'; module.exports = (function () { diff --git a/lib/google-analytics.js b/lib/google-analytics.js index 90c8474f..f13b0320 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -1,8 +1,8 @@ 'use babel'; 'use strict'; -var _ = require('lodash'); -var querystring = require('querystring'); +import _ from 'lodash'; +import querystring from 'querystring'; var cid; module.exports = (function () { diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js index f7e75a21..002fbfda 100644 --- a/lib/save-confirm-view.js +++ b/lib/save-confirm-view.js @@ -1,8 +1,8 @@ 'use babel'; 'use strict'; -var View = require('atom-space-pen-views').View; -var cscompatability = require('./cscompatability'); +import {View} from 'atom-space-pen-views'; +import cscompatability from './cscompatability'; module.exports = (function() { function SaveConfirmView() { diff --git a/lib/targets-view.js b/lib/targets-view.js index ccdc5320..00d41be3 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -1,8 +1,8 @@ 'use babel'; 'use strict'; -var SelectListView = require('atom-space-pen-views').SelectListView; -var cscompatability = require('./cscompatability'); +import {SelectListView} from 'atom-space-pen-views'; +import cscompatability from './cscompatability'; module.exports = (function() { function TargetsView() { From 41d70a73816c83a50f31f9dba38c19ca0db4da81 Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Wed, 11 Nov 2015 23:39:59 -0700 Subject: [PATCH 224/495] Convert SaveConfirmView to ES6 Class. --- lib/save-confirm-view.js | 51 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js index 002fbfda..3f6b10a4 100644 --- a/lib/save-confirm-view.js +++ b/lib/save-confirm-view.js @@ -2,38 +2,31 @@ 'use strict'; import {View} from 'atom-space-pen-views'; -import cscompatability from './cscompatability'; -module.exports = (function() { - function SaveConfirmView() { - View.apply(this, arguments); - } - - cscompatability.extends(SaveConfirmView, View); - - SaveConfirmView.content = function() { - SaveConfirmView.div({ class: 'build-confirm overlay from-top' }, function() { - SaveConfirmView.h3('You have unsaved changes'); - SaveConfirmView.div({ class: 'btn-container pull-right' }, function() { - SaveConfirmView.button({ class: 'btn btn-success', outlet: 'saveBuildButton', title: 'Save and Build', click: 'saveAndConfirm' }, 'Save and build'); - SaveConfirmView.button({ class: 'btn btn-info', title: 'Build Without Saving', click: 'confirmWithoutSave' }, 'Build Without Saving'); +export default class SaveConfirmView extends View { + static content() { + this.div({ class: 'build-confirm overlay from-top' }, () => { + this.h3('You have unsaved changes'); + this.div({ class: 'btn-container pull-right' }, () => { + this.button({ class: 'btn btn-success', outlet: 'saveBuildButton', title: 'Save and Build', click: 'saveAndConfirm' }, 'Save and build'); + this.button({ class: 'btn btn-info', title: 'Build Without Saving', click: 'confirmWithoutSave' }, 'Build Without Saving'); }); - SaveConfirmView.div({ class: 'btn-container pull-left' }, function() { - SaveConfirmView.button({ class: 'btn btn-info', title: 'Cancel', click: 'cancel' }, 'Cancel'); + this.div({ class: 'btn-container pull-left' }, () => { + this.button({ class: 'btn btn-info', title: 'Cancel', click: 'cancel' }, 'Cancel'); }); }); - }; + } - SaveConfirmView.prototype.destroy = function() { + destroy() { this.confirmcb = undefined; this.cancelcb = undefined; if (this.panel) { this.panel.destroy(); this.panel = null; } - }; + } - SaveConfirmView.prototype.show = function(confirmcb, cancelcb) { + show(confirmcb, cancelcb) { this.confirmcb = confirmcb; this.cancelcb = cancelcb; @@ -41,28 +34,26 @@ module.exports = (function() { item: this }); this.saveBuildButton.focus(); - }; + } - SaveConfirmView.prototype.cancel = function() { + cancel() { this.destroy(); if (this.cancelcb) { this.cancelcb(); } - }; + } - SaveConfirmView.prototype.saveAndConfirm = function() { + saveAndConfirm() { if (this.confirmcb) { this.confirmcb(true); } this.destroy(); - }; + } - SaveConfirmView.prototype.confirmWithoutSave = function() { + confirmWithoutSave() { if (this.confirmcb) { this.confirmcb(false); } this.destroy(); - }; - - return SaveConfirmView; -})(); + } +} From cb15e3e277ed998e1846932ac6370070d1efcc4e Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Wed, 11 Nov 2015 23:45:18 -0700 Subject: [PATCH 225/495] Remove strict. Classes are strict by default. --- lib/save-confirm-view.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js index 3f6b10a4..c0da2d7b 100644 --- a/lib/save-confirm-view.js +++ b/lib/save-confirm-view.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import {View} from 'atom-space-pen-views'; From f1d65bd13baee59069a219e3e69ea9543b1ef94c Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Thu, 12 Nov 2015 00:14:47 -0700 Subject: [PATCH 226/495] Optimize Google Analytics Class. --- lib/google-analytics.js | 49 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/lib/google-analytics.js b/lib/google-analytics.js index f13b0320..3b34e26e 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -5,16 +5,8 @@ import _ from 'lodash'; import querystring from 'querystring'; var cid; -module.exports = (function () { - atom.packages.onDidActivatePackage(function (pkg) { - if ('metrics' === pkg.name) { - var buildPackage = atom.packages.getLoadedPackage('build'); - GoogleAnalytics.sendEvent('core', 'activated', buildPackage.metadata.version); - } - }); - function GoogleAnalytics () {} - - GoogleAnalytics.getCid = function (cb) { +export default class GoogleAnalytics { + static getCid(cb) { if (cid) { return cb(cid); } @@ -26,9 +18,9 @@ module.exports = (function () { return cb(require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex')); }); - }; + } - GoogleAnalytics.sendEvent = function(category, action, label, value) { + static sendEvent(category, action, label, value) { var params = { t: 'event', ec: category, @@ -41,10 +33,10 @@ module.exports = (function () { params.ev = value; } - GoogleAnalytics.send(params); - }; + this.send(params); + } - GoogleAnalytics.send = function (params) { + static send(params) { if (!atom.packages.getActivePackage('metrics')) { // If the metrics package is disabled, then user has opted out. return; @@ -52,30 +44,35 @@ module.exports = (function () { GoogleAnalytics.getCid(function (cid) { _.extend(params, { cid: cid }, GoogleAnalytics.defaultParams()); - GoogleAnalytics.request('https://www.google-analytics.com/collect?' + querystring.stringify(params)); + this.request('https://www.google-analytics.com/collect?' + querystring.stringify(params)); }); - }; + } - GoogleAnalytics.request = function (url) { + static request(url) { if (!navigator.onLine) { return; } - GoogleAnalytics.post(url); - }; + this.post(url); + } - GoogleAnalytics.post = function (url) { + static post(url) { var xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.send(null); - }; + } - GoogleAnalytics.defaultParams = function () { + static defaultParams() { // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters return { v: 1, tid: 'UA-47615700-5', }; - }; + } +} - return GoogleAnalytics; -})(); +atom.packages.onDidActivatePackage((pkg) => { + if ('metrics' === pkg.name) { + var buildPackage = atom.packages.getLoadedPackage('build'); + GoogleAnalytics.sendEvent('core', 'activated', buildPackage.metadata.version); + } +}); From 70db9f80c0a7b27a77f104ef18acf4bb0fa28911 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 14:55:11 +0100 Subject: [PATCH 227/495] Use new capabilities of ES6 ES6 provides some very cool new features in forms of array manipulation, classes etc. Make full use of those! --- lib/atom-build.js | 20 +++--- lib/build-error.js | 11 +++ lib/build-view.js | 152 +++++++++++++++++++-------------------- lib/build.js | 105 ++++++++++++--------------- lib/cscompatability.js | 21 ------ lib/error-matcher.js | 71 ++++++++---------- lib/google-analytics.js | 20 +++--- lib/save-confirm-view.js | 2 +- lib/targets-view.js | 64 ++++++++--------- 9 files changed, 208 insertions(+), 258 deletions(-) create mode 100644 lib/build-error.js delete mode 100644 lib/cscompatability.js diff --git a/lib/atom-build.js b/lib/atom-build.js index ddb59bdb..4d1f1023 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -16,8 +16,7 @@ function getConfig(file) { return require(realFile); case '.cson': - var content = fs.readFileSync(realFile); - return CSON.parse(content); + return CSON.parse(fs.readFileSync(realFile)); } } @@ -35,10 +34,9 @@ function createBuildConfig(build, name) { } module.exports.isEligable = function (cwd) { - this.files = _([ '.atom-build.json', '.atom-build.cson' ]) - .map(file => { return path.join(cwd, file); }) - .filter(fs.existsSync) - .value(); + this.files = [ '.atom-build.json', '.atom-build.cson' ] + .map(file => path.join(cwd, file)) + .filter(fs.existsSync); return 0 < this.files.length; }; @@ -46,10 +44,10 @@ module.exports.settings = function (cwd) { let config = []; this.files.map(getConfig).forEach(build => { - config.push(createBuildConfig(build, build.name || 'default')); - _.forEach(build.targets || [], (target, name) => { - config.push(createBuildConfig(target, name)); - }); + config.push( + createBuildConfig(build, build.name || 'default'), + ..._.map(build.targets, (target, name) => createBuildConfig(target, name)) + ); }); return config; @@ -61,7 +59,7 @@ module.exports.on = function (ev, cb) { return; } - this.fileWatchers.push.apply(this.fileWatchers, this.files.map(file => fs.watch(file, cb))); + this.fileWatchers.push(...this.files.map(file => fs.watch(file, cb))); }; module.exports.off = function (ev) { diff --git a/lib/build-error.js b/lib/build-error.js new file mode 100644 index 00000000..d97a9f6b --- /dev/null +++ b/lib/build-error.js @@ -0,0 +1,11 @@ +'use babel'; +'use strict'; + +export default class BuildError extends Error { + constructor(name, message) { + super(message); + this.name = name; + this.message = message; + Error.captureStackTrace(this, BuildError); + } +} diff --git a/lib/build-view.js b/lib/build-view.js index 254cc3c5..902f328b 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -2,14 +2,13 @@ 'use strict'; import _ from 'lodash'; -import {View, $} from 'atom-space-pen-views'; +import { View, $ } from 'atom-space-pen-views'; import ansi_up from 'ansi_up'; -import cscompatability from './cscompatability'; import GoogleAnalytics from './google-analytics'; -module.exports = (function() { - function BuildView() { - View.apply(this, arguments); +export default class BuildView extends View { + constructor() { + super(...arguments); this.titleLoop = [ 'Building', 'Building.', 'Building..', 'Building...' ]; this.titleLoop.rotate = function () { /* Throttle as we don't want to update as quick as the timer is */ @@ -32,29 +31,27 @@ module.exports = (function() { atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this)); } - cscompatability.extends(BuildView, View); - - BuildView.content = function() { - BuildView.div({ tabIndex: -1, class: 'build tool-panel panel-bottom native-key-bindings' }, function() { - BuildView.div({ class: 'btn-container pull-right' }, function() { - BuildView.button({ class: 'btn btn-default icon icon-x', click: 'close' }); - BuildView.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' }); - BuildView.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clear' }); - BuildView.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' }); + static content() { + this.div({ tabIndex: -1, class: 'build tool-panel panel-bottom native-key-bindings' }, () => { + this.div({ class: 'btn-container pull-right' }, () => { + this.button({ class: 'btn btn-default icon icon-x', click: 'close' }); + this.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' }); + this.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clear' }); + this.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' }); }); - BuildView.div({ class: 'output panel-body', outlet: 'output' }); + this.div({ class: 'output panel-body', outlet: 'output' }); - BuildView.div({ class: 'status' }, function() { - BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, function () { - BuildView.span({ class: 'build-timer', outlet: 'buildTimer' }, '0.0 s'); - BuildView.span({ class: 'title-text', outlet: 'titleText' }, 'Ready'); + this.div({ class: 'status' }, () => { + this.h1({ class: 'title panel-heading', outlet: 'title' }, ()=> { + this.span({ class: 'build-timer', outlet: 'buildTimer' }, '0.0 s'); + this.span({ class: 'title-text', outlet: 'titleText' }, 'Ready'); }); }); }); - }; + } - BuildView.prototype.attach = function(force) { + attach(force) { if (!force) { switch (atom.config.get('build.panelVisibility')) { case 'Hidden': @@ -76,9 +73,9 @@ module.exports = (function() { this.panel = addfn[orientation].call(atom.workspace, { item: this }); this.sizeFromConfig(); this.fontFromConfig(); - }; + } - BuildView.prototype.detach = function(force) { + detach(force) { force = force || false; if (atom.views.getView(atom.workspace)) { atom.views.getView(atom.workspace).focus(); @@ -87,21 +84,21 @@ module.exports = (function() { this.panel.destroy(); this.panel = null; } - }; + } - BuildView.prototype.isAttached = function() { + isAttached() { return !!this.panel; - }; + } - BuildView.prototype.sizeFromConfig = function() { + sizeFromConfig() { this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight')); - }; + } - BuildView.prototype.fontFromConfig = function() { + fontFromConfig() { this.output.css('font-family', atom.config.get('editor.fontFamily')); - }; + } - BuildView.prototype.visibleFromConfig = function(val) { + visibleFromConfig(val) { switch (val) { case 'Toggle': case 'Show on Error': @@ -110,18 +107,18 @@ module.exports = (function() { } break; } - }; + } - BuildView.prototype.orientationFromConfig = function (val) { + orientationFromConfig(val) { let isVisible = this.isVisible(); this.detach(true); if (isVisible) { this.attach(); this._setMonocleIcon(); } - }; + } - BuildView.prototype.reset = function() { + reset() { clearTimeout(this.titleTimer); this.buffer = new Buffer(0); this.links = []; @@ -130,34 +127,34 @@ module.exports = (function() { this.output.empty(); this.titleText.text('Cleared.'); this.detach(); - }; + } - BuildView.prototype.updateTitle = function() { + updateTitle() { this.titleText.text(this.titleLoop[0]); this.titleLoop.rotate(); this.buildTimer.text(((new Date() - this.starttime) / 1000).toFixed(1) + ' s'); this.titleTimer = setTimeout(this.updateTitle.bind(this), 100); - }; + } - BuildView.prototype.close = function(event, element) { + close(event, element) { this.detach(true); - }; + } - BuildView.prototype.toggle = function(event, element) { + toggle(event, element) { GoogleAnalytics.sendEvent('view', 'panel toggled'); this.isAttached() ? this.detach(true) : this.attach(true); - }; + } - BuildView.prototype.clear = function(event, element) { + clear(event, element) { this.reset(); this.attach(); - }; + } - BuildView.prototype.build = function(event, element) { + build(event, element) { atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:trigger'); - }; + } - BuildView.prototype.setSizePercent = function(percent) { + setSizePercent(percent) { let size = 0, cssKey = 'height'; switch (atom.config.get('build.panelOrientation')) { case 'Top': @@ -178,9 +175,9 @@ module.exports = (function() { this.output.css('width', 'auto'); this.output.css('height', '100%'); this.output.css(cssKey, percent * size + 'px'); - }; + } - BuildView.prototype._setMonocleIcon = function () { + _setMonocleIcon() { let iconName = () => { switch (atom.config.get('build.panelOrientation')) { case 'Top': return this.monocle ? 'icon-chevron-up' : 'icon-chevron-down'; @@ -193,16 +190,16 @@ module.exports = (function() { this.monocleButton .removeClass('icon-chevron-down icon-chevron-up icon-chevron-left icon-chevron-right') .addClass(iconName()); - }; + } - BuildView.prototype.toggleMonocle = function(event, element) { + toggleMonocle(event, element) { GoogleAnalytics.sendEvent('view', 'monocle toggled'); this.monocle = !this.monocle; this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight')); this._setMonocleIcon(); - }; + } - BuildView.prototype.buildStarted = function() { + buildStarted() { this.starttime = new Date(); this.reset(); this.attach(); @@ -210,50 +207,47 @@ module.exports = (function() { this.focus(); } this.updateTitle(); - }; + } - BuildView.prototype.buildFinished = function(success) { + buildFinished(success) { if (!success) { - var force = (atom.config.get('build.panelVisibility') === 'Show on Error'); - this.attach(force); + this.attach(atom.config.get('build.panelVisibility') === 'Show on Error'); } this.titleText.text(success ? 'Build finished.' : 'Build failed.'); this.title.addClass(success ? 'success' : 'error'); clearTimeout(this.titleTimer); - }; + } - BuildView.prototype.buildAbortInitiated = function() { + buildAbortInitiated() { this.titleText.text('Build process termination imminent...'); clearTimeout(this.titleTimer); this.title.addClass('error'); - }; + } - BuildView.prototype.buildAborted = function() { + buildAborted() { this.titleText.text('Aborted!'); - }; + } - BuildView.prototype._render = function() { - var string = _.escape(this.buffer.toString('utf8')); - _.forEach(this.links, function (link, index) { - var replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); + _render() { + let string = _.escape(this.buffer.toString('utf8')); + this.links.forEach((link, index) => { + let replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); }); this.output.html(ansi_up.ansi_to_html(string)); this.output.find('a').on('click', (event) => { - var link = _.findWhere(this.links, { id: event.currentTarget.id }); - link.onClick(); + this.links.find(l => l.id === event.currentTarget.id).onClick(); }); - }; + } - BuildView.prototype.append = function(data) { + append(data) { this.buffer = Buffer.concat([ this.buffer, Buffer.isBuffer(data) ? data : new Buffer(data) ]); this._render(); this.output.scrollTop(this.output[0].scrollHeight); - }; + } - BuildView.prototype.link = function(text, id, onClick) { - if (_.findWhere(this.links, { text: text })) { - /* This text already has a link to it. Ignore it. */ + link(text, id, onClick) { + if (this.links.find(l => l.text === text)) { return; } @@ -263,14 +257,12 @@ module.exports = (function() { onClick: onClick }); this._render(); - }; + } - BuildView.prototype.scrollTo = function(id) { + scrollTo(id) { var position = this.output.find('#' + id).position(); if (position) { this.output.scrollTop(position.top + this.output.scrollTop()); } - }; - - return BuildView; -})(); + } +} diff --git a/lib/build.js b/lib/build.js index e1c2c85e..c843e6af 100644 --- a/lib/build.js +++ b/lib/build.js @@ -5,7 +5,7 @@ import child_process from 'child_process'; import fs from 'fs'; import path from 'path'; import _ from 'lodash'; -import {Disposable} from 'atom'; +import { Disposable } from 'atom'; import kill from 'tree-kill'; import SaveConfirmView from './save-confirm-view'; @@ -13,16 +13,8 @@ import TargetsView from './targets-view'; import BuildView from './build-view'; import GoogleAnalytics from './google-analytics'; import ErrorMatcher from './error-matcher'; -var tools = [ require('./atom-build') ]; - -function BuildError(name, message) { - this.name = name; - this.message = message; - Error.captureStackTrace(this, BuildError); -} - -BuildError.prototype = Object.create(Error.prototype); -BuildError.prototype.constructor = BuildError; +import BuildError from './build-error'; +let tools = [ require('./atom-build') ]; module.exports = { config: { @@ -107,10 +99,10 @@ module.exports = { this.errorMatcher = new ErrorMatcher(); atom.commands.add('atom-workspace', 'build:refresh-targets', () => this.refreshTargets()); - atom.commands.add('atom-workspace', 'build:trigger', this.build.bind(this, 'trigger')); - atom.commands.add('atom-workspace', 'build:select-active-target', this.selectActiveTarget.bind(this)); - atom.commands.add('atom-workspace', 'build:stop', this.stop.bind(this)); - atom.commands.add('atom-workspace', 'build:confirm', function() { + atom.commands.add('atom-workspace', 'build:trigger', () => this.build('trigger')); + atom.commands.add('atom-workspace', 'build:select-active-target', () => this.selectActiveTarget()); + atom.commands.add('atom-workspace', 'build:stop', () => this.stop()); + atom.commands.add('atom-workspace', 'build:confirm', () => { GoogleAnalytics.sendEvent('build', 'confirmed'); document.activeElement.click(); }); @@ -129,7 +121,7 @@ module.exports = { }); }); - this.errorMatcher.on('error', function (message) { + this.errorMatcher.on('error', (message) => { atom.notifications.addError('Error matching failed!', { detail: message }); }); @@ -138,7 +130,7 @@ module.exports = { }); this.errorMatcher.on('match', (text, id) => { - var callback = this.errorMatcher.goto.bind(this.errorMatcher, id); + let callback = this.errorMatcher.goto.bind(this.errorMatcher, id); this.buildView.link(text, id, callback); }); @@ -167,7 +159,7 @@ module.exports = { }, activePath: function () { - var textEditor = atom.workspace.getActiveTextEditor(); + let textEditor = atom.workspace.getActiveTextEditor(); if (!textEditor || !textEditor.getPath()) { /* default to building the first one if no editor is active */ if (0 === atom.project.getPaths().length) { @@ -178,7 +170,7 @@ module.exports = { } else { /* otherwise, build the one in the root of the active editor */ return atom.project.getPaths().sort((a, b) => (b.length - a.length)).find(path => { - var realpath = fs.realpathSync(path); + let realpath = fs.realpathSync(path); return textEditor.getPath().substr(0, realpath.length) === realpath; }); } @@ -248,12 +240,12 @@ module.exports = { } GoogleAnalytics.sendEvent('keymap', 'registered', setting.keymap); - var commandName = 'build:trigger:' + setting.name; - var keymapSpec = { 'atom-workspace': {} }; + let commandName = 'build:trigger:' + setting.name; + let keymapSpec = { 'atom-workspace': {} }; keymapSpec['atom-workspace'][setting.keymap] = commandName; - var keymapDispose = atom.keymaps.add(setting.name, keymapSpec); - var commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); - settings[index].dispose = function () { + let keymapDispose = atom.keymaps.add(setting.name, keymapSpec); + let commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); + settings[index].dispose = () => { keymapDispose.dispose(); commandDispose.dispose(); }; @@ -292,35 +284,35 @@ module.exports = { let workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); - }).catch(function (err) { - targetsView.setError(err.message); - }); + }).catch((err) => targetsView.setError(err.message)); }, replace: function(value, targetEnv) { - var env = _.extend(_.clone(process.env), targetEnv); + let env = _.extend(_.clone(process.env), targetEnv); value = value.replace(/\$(\w+)/g, function(match, name) { return name in env ? env[name] : match; }); - var editor = atom.workspace.getActiveTextEditor(); + let editor = atom.workspace.getActiveTextEditor(); + + let projectPaths = _.map(atom.project.getPaths(), (projectPath) => { + try { + return fs.realpathSync(projectPath); + } catch (e) {} + }); + + let projectPath = projectPaths[0]; if (editor && 'untitled' !== editor.getTitle()) { - var activeFile = fs.realpathSync(editor.getPath()); - var activeFilePath = path.dirname(activeFile); + let activeFile = fs.realpathSync(editor.getPath()); + let activeFilePath = path.dirname(activeFile); + projectPath = _.find(projectPaths, function(projectPath) { + return activeFilePath && activeFilePath.startsWith(projectPath); + }); value = value.replace(/{FILE_ACTIVE}/g, activeFile); value = value.replace(/{FILE_ACTIVE_PATH}/g, activeFilePath); value = value.replace(/{FILE_ACTIVE_NAME}/g, path.basename(activeFile)); value = value.replace(/{FILE_ACTIVE_NAME_BASE}/g, path.basename(activeFile, path.extname(activeFile))); } - var projectPaths = _.map(atom.project.getPaths(), function(projectPath) { - try { - return fs.realpathSync(projectPath); - } catch (e) {} - }); - var projectPath = _.find(projectPaths, function(projectPath) { - return activeFilePath && activeFilePath.startsWith(projectPath); - }) || projectPaths[0]; - value = value.replace(/{PROJECT_PATH}/g, projectPath); if (atom.project.getRepositories[0]) { value = value.replace(/{REPO_BRANCH_SHORT}/g, atom.project.getRepositories()[0].getShortHead()); @@ -331,26 +323,27 @@ module.exports = { startNewBuild: function(source, targetName) { let path = this.activePath(); + targetName = targetName || this.activeTarget[path]; Promise.resolve(this.targets[path]).then(targets => { if (!targets) { throw new BuildError('No eligible build target.', 'No configuration to build this project exists.'); } - let target = targets.find(target => (targetName) ? target.name === targetName : target.name === this.activeTarget[path]); + let target = targets.find(target => target.name === targetName); GoogleAnalytics.sendEvent('build', 'triggered'); if (!target.exec) { throw new BuildError('Inavlid build file.', 'No executable command specified.'); } - var env = _.extend(_.clone(process.env), target.env); - _.each(env, (value, key, list) => { + let env = _.extend({}, process.env, target.env); + _.forEach(env, (value, key, list) => { list[key] = this.replace(value, target.env); }); let exec = this.replace(target.exec, target.env); - var args = _.map(target.args, (arg) => this.replace(arg, target.env)); + let args = target.args.map(arg => this.replace(arg, target.env)); let cwd = this.replace(target.cwd, target.env); this.child = child_process.spawn( @@ -386,7 +379,7 @@ module.exports = { this.child.on('close', (exitCode) => { this.errorMatcher.set(target.errorMatch, cwd, this.buildView.output.text()); - var success = 0 === exitCode && !this.errorMatcher.hasMatch(); + let success = 0 === exitCode && !this.errorMatcher.hasMatch(); this.buildView.buildFinished(success); if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); @@ -403,8 +396,8 @@ module.exports = { }); this.buildView.buildStarted(); - this.buildView.append((target.sh ? 'Executing with sh: ' : 'Executing: ') + exec + [ ' ' ].concat(args).join(' ') + '\n'); - }).catch(function (err) { + this.buildView.append([ (target.sh ? 'Executing with sh:' : 'Executing:'), exec, ...args, '\n'].join(' ')); + }).catch((err) => { if (err instanceof BuildError) { if (source === 'save') { // If there is no eligible build tool, and cause of build was a save, stay quiet. @@ -420,9 +413,7 @@ module.exports = { this.child.removeAllListeners('close'); this.child.on('close', () => { this.child = null; - if (cb) { - cb(); - } + cb && cb(); }); try { @@ -438,16 +429,14 @@ module.exports = { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), () => { - var next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); + let next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); this.child ? this.abort(next) : next(); }); }, doSaveConfirm: function(modifiedTextEditors, continuecb, cancelcb) { - var saveAndContinue = function(save) { - _.each(modifiedTextEditors, function(textEditor) { - save && textEditor.save(); - }); + let saveAndContinue = (save) => { + modifiedTextEditors.forEach((textEditor) => save && textEditor.save()); continuecb(); }; @@ -464,7 +453,7 @@ module.exports = { }, unsavedTextEditors: function() { - return _.filter(atom.workspace.getTextEditors(), function(textEditor) { + return atom.workspace.getTextEditors().filter((textEditor) => { return textEditor.isModified() && ('untitled' !== textEditor.getTitle()); }); }, @@ -481,7 +470,7 @@ module.exports = { return; } - this.abort(this.buildView.buildAborted.bind(this.buildView)); + this.abort(() => this.buildView.buildAborted()); this.buildView.buildAbortInitiated(); } else { @@ -494,7 +483,7 @@ module.exports = { builders = [ builders ]; } tools = _.union(tools, builders); - return new Disposable(function () { + return new Disposable(() => { tools = _.difference(tools, builders); }); } diff --git a/lib/cscompatability.js b/lib/cscompatability.js deleted file mode 100644 index 5179046f..00000000 --- a/lib/cscompatability.js +++ /dev/null @@ -1,21 +0,0 @@ -'use babel'; -'use strict'; - -/* jshint newcap:false */ -var __hasProp = {}.hasOwnProperty; - -module.exports.extends = function(child, parent) { - for (var key in parent) { - if (__hasProp.call(parent, key)) { - child[key] = parent[key]; - } - } - function ctor() { - /* jshint validthis:true */ - this.constructor = child; - } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); - child.__super__ = parent.prototype; - return child; -}; diff --git a/lib/error-matcher.js b/lib/error-matcher.js index cc675e2f..c2782526 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -3,15 +3,14 @@ import fs from 'fs'; import path from 'path'; -import {XRegExp} from 'xregexp'; +import { XRegExp } from 'xregexp'; +import { EventEmitter } from 'events'; import GoogleAnalytics from './google-analytics'; -import {EventEmitter} from 'events'; -import util from 'util'; -import _ from 'lodash'; -module.exports = (function () { +export default class ErrorMatcher extends EventEmitter { - function ErrorMatcher() { + constructor() { + super(); this.regex = null; this.cwd = null; this.stdout = null; @@ -23,18 +22,16 @@ module.exports = (function () { atom.commands.add('atom-workspace', 'build:error-match-first', this.matchFirst.bind(this)); } - util.inherits(ErrorMatcher, EventEmitter); - - ErrorMatcher.prototype._gotoNext = function () { + _gotoNext() { if (0 === this.currentMatch.length) { return; } this.goto(this.currentMatch[0].id); - }; + } - ErrorMatcher.prototype.goto = function (id) { - var match = _.findWhere(this.currentMatch, { id: id }); + goto(id) { + let match = this.currentMatch.find(m => m.id === id); if (!match) { return this.emit('error', 'Can\'t find match with id ' + id); } @@ -54,8 +51,8 @@ module.exports = (function () { file = this.cwd + path.sep + file; } - var row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ - var col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ + let row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ + let col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ fs.exists(file, (exists) => { if (!exists) { @@ -68,12 +65,12 @@ module.exports = (function () { }); this.emit('matched', match.id); }); - }; + } - ErrorMatcher.prototype._parse = function () { + _parse() { this.currentMatch = []; - var self = this; - var matchFunction = function (match, i, string, regex) { + let self = this; + let matchFunction = function (match, i, string, regex) { match.id = 'error-match-' + self.regex.indexOf(regex) + '-' + i; this.push(match); }; @@ -81,56 +78,48 @@ module.exports = (function () { XRegExp.forEach(this.output, regex, matchFunction, this.currentMatch); }); - this.currentMatch.sort(function(a, b) { - return a.index - b.index; - }); + this.currentMatch.sort((a, b) => a.index - b.index); this.firstMatchId = (this.currentMatch.length > 0) ? this.currentMatch[0].id : null; - _.forEach(this.currentMatch, (match, index) => { - this.emit('match', match[0], match.id); - }); - }; + this.currentMatch.forEach((match, index) => this.emit('match', match[0], match.id)); + } - ErrorMatcher.prototype.set = function (regex, cwd, output) { - if (!regex) { - regex = []; - } + set(regex, cwd, output) { + regex = regex || []; regex = (regex instanceof Array) ? regex : [ regex ]; - this.regex = _.compact(regex.map((r) => { + this.regex = regex.map((r) => { try { return XRegExp(r); } catch (err) { this.emit('error', 'Error parsing regex. ' + err.message); return null; } - })); + }).filter(Boolean); this.cwd = cwd; this.output = output; this.currentMatch = []; this._parse(); - }; + } - ErrorMatcher.prototype.match = function () { + match() { GoogleAnalytics.sendEvent('errorMatch', 'match'); this._gotoNext(); - }; + } - ErrorMatcher.prototype.matchFirst = function () { + matchFirst() { GoogleAnalytics.sendEvent('errorMatch', 'first'); if (this.firstMatchId) { this.goto(this.firstMatchId); } - }; + } - ErrorMatcher.prototype.hasMatch = function () { + hasMatch() { return 0 !== this.currentMatch.length; - }; - - return ErrorMatcher; -})(); + } +} diff --git a/lib/google-analytics.js b/lib/google-analytics.js index 3b34e26e..acfbfb50 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -3,7 +3,7 @@ import _ from 'lodash'; import querystring from 'querystring'; -var cid; +let cid; export default class GoogleAnalytics { static getCid(cb) { @@ -11,17 +11,15 @@ export default class GoogleAnalytics { return cb(cid); } - require('getmac').getMac(function(error, macAddress) { - if (error) { - return cb(cid = require('node-uuid').v4()); - } - - return cb(require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex')); + require('getmac').getMac((error, macAddress) => { + return error ? + cb(cid = require('node-uuid').v4()) : + cb(require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex')); }); } static sendEvent(category, action, label, value) { - var params = { + let params = { t: 'event', ec: category, ea: action @@ -42,7 +40,7 @@ export default class GoogleAnalytics { return; } - GoogleAnalytics.getCid(function (cid) { + GoogleAnalytics.getCid((cid) => { _.extend(params, { cid: cid }, GoogleAnalytics.defaultParams()); this.request('https://www.google-analytics.com/collect?' + querystring.stringify(params)); }); @@ -56,7 +54,7 @@ export default class GoogleAnalytics { } static post(url) { - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.send(null); } @@ -72,7 +70,7 @@ export default class GoogleAnalytics { atom.packages.onDidActivatePackage((pkg) => { if ('metrics' === pkg.name) { - var buildPackage = atom.packages.getLoadedPackage('build'); + let buildPackage = atom.packages.getLoadedPackage('build'); GoogleAnalytics.sendEvent('core', 'activated', buildPackage.metadata.version); } }); diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js index c0da2d7b..c6d7eeb5 100644 --- a/lib/save-confirm-view.js +++ b/lib/save-confirm-view.js @@ -1,6 +1,6 @@ 'use babel'; -import {View} from 'atom-space-pen-views'; +import { View } from 'atom-space-pen-views'; export default class SaveConfirmView extends View { static content() { diff --git a/lib/targets-view.js b/lib/targets-view.js index 00d41be3..ff576777 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -1,77 +1,71 @@ 'use babel'; 'use strict'; -import {SelectListView} from 'atom-space-pen-views'; -import cscompatability from './cscompatability'; +import { SelectListView } from 'atom-space-pen-views'; -module.exports = (function() { - function TargetsView() { - SelectListView.apply(this, arguments); +export default class TargetsView extends SelectListView { + + constructor() { + super(...arguments); this.show(); } - cscompatability.extends(TargetsView, SelectListView); - - TargetsView.prototype.initialize = function () { - TargetsView.__super__.initialize.apply(this, arguments); + initialize() { + super.initialize(...arguments); this.list.addClass('mark-active'); - }; + } - TargetsView.prototype.show = function() { - this.panel = atom.workspace.addModalPanel({ - item: this - }); + show() { + this.panel = atom.workspace.addModalPanel({ item: this }); this.panel.show(); this.focusFilterEditor(); - }; + } - TargetsView.prototype.hide = function () { + hide() { this.panel.hide(); - }; + } - TargetsView.prototype.setItems = function () { - TargetsView.__super__.setItems.apply(this, arguments); + setItems() { + super.setItems(...arguments); var activeItemView = this.find('.active'); if (0 < activeItemView.length) { this.selectItemView(activeItemView); this.scrollToItemView(activeItemView); } - }; + } - TargetsView.prototype.setActiveTarget = function (target) { + setActiveTarget(target) { this.activeTarget = target; - }; + } - TargetsView.prototype.viewForItem = function(targetName) { + viewForItem(targetName) { var activeTarget = this.activeTarget; return TargetsView.render(function() { var activeClass = (targetName === activeTarget ? 'active' : ''); this.li({ class: activeClass + ' build-target' }, targetName); }); - }; + } - TargetsView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) { + getEmptyMessage(itemCount, filteredItemCount) { return (0 === itemCount) ? 'No targets found.' : 'No matches'; - }; + } - TargetsView.prototype.awaitSelection = function () { + awaitSelection() { return new Promise((resolve, reject) => { this.resolveFunction = resolve; }); - }; + } - TargetsView.prototype.confirmed = function(target) { + confirmed(target) { if (this.resolveFunction) { this.resolveFunction(target); this.resolveFunction = null; } this.hide(); - }; + } - TargetsView.prototype.cancelled = function() { + cancelled() { this.hide(); - }; - - return TargetsView; -})(); + } +} From 56758d718c3322b009ceddc3007b6e0de0cd13ec Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 15:34:21 +0100 Subject: [PATCH 228/495] JSHint/JSCS -> ESLint Because it's better. That's why. --- .eslintrc | 22 ++++++++++++++++++++++ .travis.yml | 1 - lib/atom-build.js | 14 ++++++-------- lib/build-error.js | 1 - lib/build-view.js | 17 ++++++++--------- lib/build.js | 9 ++++----- lib/error-matcher.js | 3 +-- lib/google-analytics.js | 3 +-- lib/save-confirm-view.js | 6 +++--- lib/targets-view.js | 3 +-- package.json | 10 +++++----- spec/build-confirm-spec.js | 1 - spec/build-error-match-spec.js | 2 +- spec/build-keymap-spec.js | 1 - spec/build-spec.js | 3 +-- spec/build-targets-spec.js | 1 - spec/build-view-spec.js | 9 ++++----- spec/build-visible-spec.js | 1 - 18 files changed, 57 insertions(+), 50 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..a9220583 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,22 @@ +{ + "parser": "babel-eslint", + "rules": { + "strict": [ 2, "never" ], + "indent": [ 2, 2, { "SwitchCase": 1 } ], + "quotes": [ 2, "single" ], + "linebreak-style": [ 2, "unix" ], + "semi": [ 2, "always" ], + "no-unused-vars": [ 2, { "vars": "all", "args": "none" } ] + }, + "env": { + "es6": true, + "node": true, + "browser": true, + "jasmine": true + }, + "globals": { + "atom": true, + "waitsForPromise": true + }, + "extends": "eslint:recommended" +} diff --git a/.travis.yml b/.travis.yml index 4b1209ae..a665217e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,6 @@ notifications: before_script: - npm install - - npm test script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh' diff --git a/lib/atom-build.js b/lib/atom-build.js index 4d1f1023..b70adaf3 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import path from 'path'; import fs from 'fs'; @@ -12,11 +11,11 @@ function getConfig(file) { var realFile = fs.realpathSync(file); delete require.cache[realFile]; switch (path.extname(file)) { - case '.json': - return require(realFile); + case '.json': + return require(realFile); - case '.cson': - return CSON.parse(fs.readFileSync(realFile)); + case '.cson': + return CSON.parse(fs.readFileSync(realFile)); } } @@ -40,12 +39,11 @@ module.exports.isEligable = function (cwd) { return 0 < this.files.length; }; -module.exports.settings = function (cwd) { - +module.exports.settings = function () { let config = []; this.files.map(getConfig).forEach(build => { config.push( - createBuildConfig(build, build.name || 'default'), + createBuildConfig(build, build.name || 'default'), ..._.map(build.targets, (target, name) => createBuildConfig(target, name)) ); }); diff --git a/lib/build-error.js b/lib/build-error.js index d97a9f6b..80b403c3 100644 --- a/lib/build-error.js +++ b/lib/build-error.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; export default class BuildError extends Error { constructor(name, message) { diff --git a/lib/build-view.js b/lib/build-view.js index 902f328b..d2432291 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import _ from 'lodash'; import { View, $ } from 'atom-space-pen-views'; @@ -76,7 +75,7 @@ export default class BuildView extends View { } detach(force) { - force = force || false; + force = force || false; if (atom.views.getView(atom.workspace)) { atom.views.getView(atom.workspace).focus(); } @@ -109,7 +108,7 @@ export default class BuildView extends View { } } - orientationFromConfig(val) { + orientationFromConfig() { let isVisible = this.isVisible(); this.detach(true); if (isVisible) { @@ -136,21 +135,21 @@ export default class BuildView extends View { this.titleTimer = setTimeout(this.updateTitle.bind(this), 100); } - close(event, element) { + close() { this.detach(true); } - toggle(event, element) { + toggle() { GoogleAnalytics.sendEvent('view', 'panel toggled'); this.isAttached() ? this.detach(true) : this.attach(true); } - clear(event, element) { + clear() { this.reset(); this.attach(); } - build(event, element) { + build() { atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:trigger'); } @@ -192,7 +191,7 @@ export default class BuildView extends View { .addClass(iconName()); } - toggleMonocle(event, element) { + toggleMonocle() { GoogleAnalytics.sendEvent('view', 'monocle toggled'); this.monocle = !this.monocle; this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight')); @@ -230,7 +229,7 @@ export default class BuildView extends View { _render() { let string = _.escape(this.buffer.toString('utf8')); - this.links.forEach((link, index) => { + this.links.forEach((link) => { let replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); }); diff --git a/lib/build.js b/lib/build.js index c843e6af..9bb13420 100644 --- a/lib/build.js +++ b/lib/build.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import child_process from 'child_process'; import fs from 'fs'; @@ -82,7 +81,7 @@ module.exports = { } }, - activate: function(state) { + activate: function() { // Manually append /usr/local/bin as it may not be set on some systems, // and it's common to have node installed here. Keep it at end so it won't // accidentially override any other node installation @@ -114,7 +113,7 @@ module.exports = { }); atom.workspace.observeTextEditors((editor) => { - editor.onDidSave((event) => { + editor.onDidSave(() => { if (atom.config.get('build.buildOnSave')) { this.build('save'); } @@ -147,7 +146,7 @@ module.exports = { deactivate: function() { tools.forEach(tool => { if (tool.off) { - _.forEach(tool.ctx, (ctx, path) => tool.off.apply(ctx, [ 'refresh' ])); + _.forEach(tool.ctx, ctx => tool.off.apply(ctx, [ 'refresh' ])); } }); if (this.child) { @@ -298,7 +297,7 @@ module.exports = { let projectPaths = _.map(atom.project.getPaths(), (projectPath) => { try { return fs.realpathSync(projectPath); - } catch (e) {} + } catch (e) { Function.prototype(); } }); let projectPath = projectPaths[0]; diff --git a/lib/error-matcher.js b/lib/error-matcher.js index c2782526..2ad23910 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import fs from 'fs'; import path from 'path'; @@ -82,7 +81,7 @@ export default class ErrorMatcher extends EventEmitter { this.firstMatchId = (this.currentMatch.length > 0) ? this.currentMatch[0].id : null; - this.currentMatch.forEach((match, index) => this.emit('match', match[0], match.id)); + this.currentMatch.forEach(match => this.emit('match', match[0], match.id)); } set(regex, cwd, output) { diff --git a/lib/google-analytics.js b/lib/google-analytics.js index acfbfb50..babf0461 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import _ from 'lodash'; import querystring from 'querystring'; @@ -63,7 +62,7 @@ export default class GoogleAnalytics { // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters return { v: 1, - tid: 'UA-47615700-5', + tid: 'UA-47615700-5' }; } } diff --git a/lib/save-confirm-view.js b/lib/save-confirm-view.js index c6d7eeb5..366c26a2 100644 --- a/lib/save-confirm-view.js +++ b/lib/save-confirm-view.js @@ -7,11 +7,11 @@ export default class SaveConfirmView extends View { this.div({ class: 'build-confirm overlay from-top' }, () => { this.h3('You have unsaved changes'); this.div({ class: 'btn-container pull-right' }, () => { - this.button({ class: 'btn btn-success', outlet: 'saveBuildButton', title: 'Save and Build', click: 'saveAndConfirm' }, 'Save and build'); - this.button({ class: 'btn btn-info', title: 'Build Without Saving', click: 'confirmWithoutSave' }, 'Build Without Saving'); + this.button({ class: 'btn btn-success', outlet: 'saveBuildButton', title: 'Save and Build', click: 'saveAndConfirm' }, 'Save and build'); + this.button({ class: 'btn btn-info', title: 'Build Without Saving', click: 'confirmWithoutSave' }, 'Build Without Saving'); }); this.div({ class: 'btn-container pull-left' }, () => { - this.button({ class: 'btn btn-info', title: 'Cancel', click: 'cancel' }, 'Cancel'); + this.button({ class: 'btn btn-info', title: 'Cancel', click: 'cancel' }, 'Cancel'); }); }); } diff --git a/lib/targets-view.js b/lib/targets-view.js index ff576777..ebdc8a03 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; import { SelectListView } from 'atom-space-pen-views'; @@ -47,7 +46,7 @@ export default class TargetsView extends SelectListView { }); } - getEmptyMessage(itemCount, filteredItemCount) { + getEmptyMessage(itemCount) { return (0 === itemCount) ? 'No targets found.' : 'No matches'; } diff --git a/package.json b/package.json index cd855176..2f882687 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ "cson-parser": "^1.2.0" }, "devDependencies": { + "atom-build-spec-helpers": "^0.3.0", + "babel-eslint": "^4.1.5", + "eslint": "^1.10.1", "fs-extra": "^0.23.0", - "temp": "^0.8.1", - "atom-build-spec-helpers": "^0.2.0", - "jshint": "^2.5.11", - "jscs": "^1.9.0" + "temp": "^0.8.1" }, "consumedServices": { "builder": { @@ -33,7 +33,7 @@ } }, "scripts": { - "test": "./node_modules/.bin/jscs lib/*.js spec/*.js && ./node_modules/.bin/jshint lib/*.js spec/*.js" + "test": "./node_modules/.bin/eslint ." }, "keywords": [ "build", diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 7dbc8e0f..a0c3b69f 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; var _ = require('lodash'); var fs = require('fs-extra'); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index a32b23bb..1af75fe0 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,4 +1,4 @@ -'use strict'; +'use babel'; var fs = require('fs-extra'); var temp = require('temp'); diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index bd436f18..e5948773 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; var fs = require('fs-extra'); var temp = require('temp'); diff --git a/spec/build-spec.js b/spec/build-spec.js index 18ef1254..5e577e2a 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; var fs = require('fs-extra'); var temp = require('temp'); @@ -463,7 +462,7 @@ describe('Build', function() { waitsForPromise(function () { return Promise.all([ specHelpers.refreshAwaitTargets(), - atom.workspace.open(directory2 + '/main.c'), + atom.workspace.open(directory2 + '/main.c') ]); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 082ce4ee..24c819f1 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; var _ = require('lodash'); var fs = require('fs-extra'); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index fd11ac3e..ad701a85 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; var fs = require('fs-extra'); var temp = require('temp'); @@ -189,7 +188,7 @@ describe('BuildView', function() { atom.config.set('build.panelOrientation', 'Bottom'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo this will fail && exit 1', + cmd: 'echo this will fail && exit 1' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -213,7 +212,7 @@ describe('BuildView', function() { atom.config.set('build.panelOrientation', 'Left'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo this will fail && exit 1', + cmd: 'echo this will fail && exit 1' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -237,7 +236,7 @@ describe('BuildView', function() { atom.config.set('build.panelOrientation', 'Top'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo this will fail && exit 1', + cmd: 'echo this will fail && exit 1' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -261,7 +260,7 @@ describe('BuildView', function() { atom.config.set('build.panelOrientation', 'Right'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo this will fail && exit 1', + cmd: 'echo this will fail && exit 1' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index 528f8a37..af96dc28 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -1,5 +1,4 @@ 'use babel'; -'use strict'; var fs = require('fs-extra'); var temp = require('temp'); From 58b96d20f93a752a1bf99dc1add0defe3ffaa860 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 15:49:59 +0100 Subject: [PATCH 229/495] Removed .jscsrc and .jshintrc --- .jscsrc | 34 ---------------------------------- .jshintrc | 48 ------------------------------------------------ 2 files changed, 82 deletions(-) delete mode 100644 .jscsrc delete mode 100644 .jshintrc diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index ac6797aa..00000000 --- a/.jscsrc +++ /dev/null @@ -1,34 +0,0 @@ -{ - "requireCurlyBraces": [ "if", "else", "for", "while", "do", "try", "catch" ], - "requireSpaceAfterKeywords": [ "if", "else", "for", "while", "do", "switch", "return", "try", "catch" ], - "requireParenthesesAroundIIFE": true, - "requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true }, - "disallowEmptyBlocks": true, - "requireSpacesInsideObjectBrackets": "all", - "disallowSpaceAfterObjectKeys": true, - "requireCommaBeforeLineBreak": true, - "requireOperatorBeforeLineBreak": [ "?", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<=" ], - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "disallowSpaceAfterPrefixUnaryOperators": [ "++", "--", "+", "-", "~", "!" ], - "disallowSpaceBeforePostfixUnaryOperators": [ "++", "--" ], - "requireSpaceBeforeBinaryOperators": [ "+", "-", "/", "*", "=", "==", "===", "!=", "!==" ], - "requireSpaceAfterBinaryOperators": [ "+", "-", "/", "*", "=", "==", "===", "!=", "!==" ], - "disallowKeywords": [ "with", "eval" ], - "disallowMultipleLineStrings": true, - "disallowMultipleLineBreaks": true, - "validateLineBreaks": "LF", - "disallowMixedSpacesAndTabs": true, - "disallowKeywordsOnNewLine": [ "else" ], - "requireLineFeedAtFileEnd": true, - "maximumLineLength": 180, - "excludeFiles": [ - "node_modules/**", - "spec/fixture/node_modules/**" - ], - "esnext": true -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 8174af36..00000000 --- a/.jshintrc +++ /dev/null @@ -1,48 +0,0 @@ -{ - // Restricting options - "strict": true, // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode - "trailing": true, // Makes it an error to leave a trailing whitespace in your code. - "curly": true, // Force braces around blocks in loops and conditionals. - "undef": true, // Prohibits the use of explicitly undeclared variables. Use /*global ... */ for exceptions - "latedef": true, // Prohibits the use of a variable before it has been defined. - "unused": "vars", // Warns when you define and never use your variables. - "newcap": false, // Forces you to capitalize names of constructor functions. - "noarg": true, // Prohibits the use of arguments.caller and arguments.callee, which are deprecated in EcmaScript 5. - "quotmark": "single", // Force single quotes for strings - - // Relaxing options - "expr": true, // Allow expressions where normally you would expect to see assignments or function calls. - "onecase": true, // Allow switches with only one case (not counting default) - "sub": true, // Allow using [] notation when it can also be expressed in dot notation: person['name'] vs. person.name. - "esnext": true, - - // Environment - "node": true, // Define common browser globals: require, nodule, etc. - "devel": true, // Define globals that are usually used for debugging: console, alert, etc. - "globals": { // Define globals that are not defined per default - "window": false, - "navigator": false, - "XMLHttpRequest": false, - "document": false, - "atom": false, - "module": false, - // Jasmine - "jasmine": false, - "before": false, - "beforeEach": false, - "after": false, - "afterEach": false, - "describe": false, - "it": false, - "xit": false, - "waits": false, - "waitsFor": false, - "waitsForPromise": false, - "runs": false, - "expect": false - }, - - // Misc. - "white": true, // Enforce Crockford style guides - "indent": 2 // Set indentation to two spaces -} From 94104627dbb5e176b8ab8c82fee6fa2c0032a5b4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 15:50:11 +0100 Subject: [PATCH 230/495] Do not call Function.prototype A comment will please the linter just as well. --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 9bb13420..c1be3a55 100644 --- a/lib/build.js +++ b/lib/build.js @@ -297,7 +297,7 @@ module.exports = { let projectPaths = _.map(atom.project.getPaths(), (projectPath) => { try { return fs.realpathSync(projectPath); - } catch (e) { Function.prototype(); } + } catch (e) { /* Do nothing. */ } }); let projectPath = projectPaths[0]; From 729bf55c5bf7f4dfd36c7f57eb7b3789c9e2b613 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 15:51:36 +0100 Subject: [PATCH 231/495] Lint error to test that travis catches it --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index d2432291..9e76d2b2 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -17,7 +17,7 @@ export default class BuildView extends View { this.monocle = false; this.starttime = new Date(); this.buffer = new Buffer(0); - this.links = []; + this.links = [] this._setMonocleIcon(); From c3812814eb00df3fd6069ef0292d2396416faa5a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 15:54:00 +0100 Subject: [PATCH 232/495] Revert "Lint error to test that travis catches it" This reverts commit 729bf55c5bf7f4dfd36c7f57eb7b3789c9e2b613. --- lib/build-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 9e76d2b2..d2432291 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -17,7 +17,7 @@ export default class BuildView extends View { this.monocle = false; this.starttime = new Date(); this.buffer = new Buffer(0); - this.links = [] + this.links = []; this._setMonocleIcon(); From e0ac8ce06037f54b289dd8c13be9c687d6fc1714 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 18:08:25 +0100 Subject: [PATCH 233/495] Use AirBNB javascript style guide ESLint can enforce it --- .eslintrc | 20 ++- lib/atom-build.js | 4 +- lib/build-view.js | 26 ++-- lib/build.js | 146 +++++++++--------- lib/error-matcher.js | 12 +- lib/google-analytics.js | 15 +- lib/targets-view.js | 8 +- package.json | 2 + spec/build-confirm-spec.js | 122 +++++++-------- spec/build-error-match-spec.js | 261 ++++++++++++++++----------------- spec/build-keymap-spec.js | 84 ++++++----- spec/build-spec.js | 237 +++++++++++++++--------------- spec/build-targets-spec.js | 111 +++++++------- spec/build-view-spec.js | 109 +++++++------- spec/build-visible-spec.js | 77 +++++----- 15 files changed, 618 insertions(+), 616 deletions(-) diff --git a/.eslintrc b/.eslintrc index a9220583..0c371ad1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,12 +1,16 @@ { "parser": "babel-eslint", "rules": { - "strict": [ 2, "never" ], + "comma-dangle": 0, + "default-case": 0, + "func-names": 0, "indent": [ 2, 2, { "SwitchCase": 1 } ], - "quotes": [ 2, "single" ], - "linebreak-style": [ 2, "unix" ], - "semi": [ 2, "always" ], - "no-unused-vars": [ 2, { "vars": "all", "args": "none" } ] + "new-cap": [ 2, { "capIsNewExceptions": [ "XRegExp" ] } ], + "no-param-reassign": 0, + "no-unused-expressions": [ 2, { "allowTernary": true, "allowShortCircuit": true } ], + "no-unused-vars": [ 2, { "args": "none" } ], + "space-before-function-paren": [ 2, { "anonymous": "always", "named": "never" } ], + "yoda": 0 }, "env": { "es6": true, @@ -16,7 +20,9 @@ }, "globals": { "atom": true, - "waitsForPromise": true + "waitsForPromise": true, + "fit": false, + "fdescribe": false }, - "extends": "eslint:recommended" + "extends": "airbnb" } diff --git a/lib/atom-build.js b/lib/atom-build.js index b70adaf3..9fcdc346 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -8,7 +8,7 @@ import CSON from 'cson-parser'; module.exports.niceName = 'Custom file'; function getConfig(file) { - var realFile = fs.realpathSync(file); + const realFile = fs.realpathSync(file); delete require.cache[realFile]; switch (path.extname(file)) { case '.json': @@ -40,7 +40,7 @@ module.exports.isEligable = function (cwd) { }; module.exports.settings = function () { - let config = []; + const config = []; this.files.map(getConfig).forEach(build => { config.push( createBuildConfig(build, build.name || 'default'), diff --git a/lib/build-view.js b/lib/build-view.js index d2432291..124287d9 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import { View, $ } from 'atom-space-pen-views'; -import ansi_up from 'ansi_up'; +import ansiUp from 'ansi_up'; import GoogleAnalytics from './google-analytics'; export default class BuildView extends View { @@ -12,7 +12,10 @@ export default class BuildView extends View { this.titleLoop.rotate = function () { /* Throttle as we don't want to update as quick as the timer is */ this.n = this.n || 0; - (++this.n === 3) && this.push(this.shift()) && (this.n = 0); + if (++this.n === 3) { + this.push(this.shift()); + this.n = 0; + } }; this.monocle = false; this.starttime = new Date(); @@ -62,13 +65,13 @@ export default class BuildView extends View { if (this.panel) { this.panel.destroy(); } - let addfn = { + const addfn = { Top: atom.workspace.addTopPanel, Bottom: atom.workspace.addBottomPanel, Left: atom.workspace.addLeftPanel, Right: atom.workspace.addRightPanel }; - let orientation = atom.config.get('build.panelOrientation') || 'Bottom'; + const orientation = atom.config.get('build.panelOrientation') || 'Bottom'; this.panel = addfn[orientation].call(atom.workspace, { item: this }); this.sizeFromConfig(); this.fontFromConfig(); @@ -109,7 +112,7 @@ export default class BuildView extends View { } orientationFromConfig() { - let isVisible = this.isVisible(); + const isVisible = this.isVisible(); this.detach(true); if (isVisible) { this.attach(); @@ -141,7 +144,7 @@ export default class BuildView extends View { toggle() { GoogleAnalytics.sendEvent('view', 'panel toggled'); - this.isAttached() ? this.detach(true) : this.attach(true); + this.isAttached() ? this.detach(true) : this.attach(true); } clear() { @@ -154,7 +157,8 @@ export default class BuildView extends View { } setSizePercent(percent) { - let size = 0, cssKey = 'height'; + let size = 0; + let cssKey = 'height'; switch (atom.config.get('build.panelOrientation')) { case 'Top': case 'Bottom': @@ -177,7 +181,7 @@ export default class BuildView extends View { } _setMonocleIcon() { - let iconName = () => { + const iconName = () => { switch (atom.config.get('build.panelOrientation')) { case 'Top': return this.monocle ? 'icon-chevron-up' : 'icon-chevron-down'; case 'Bottom': return this.monocle ? 'icon-chevron-down' : 'icon-chevron-up'; @@ -230,10 +234,10 @@ export default class BuildView extends View { _render() { let string = _.escape(this.buffer.toString('utf8')); this.links.forEach((link) => { - let replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); + const replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); }); - this.output.html(ansi_up.ansi_to_html(string)); + this.output.html(ansiUp.ansi_to_html(string)); this.output.find('a').on('click', (event) => { this.links.find(l => l.id === event.currentTarget.id).onClick(); }); @@ -259,7 +263,7 @@ export default class BuildView extends View { } scrollTo(id) { - var position = this.output.find('#' + id).position(); + const position = this.output.find('#' + id).position(); if (position) { this.output.scrollTop(position.top + this.output.scrollTop()); } diff --git a/lib/build.js b/lib/build.js index c1be3a55..aa4031fc 100644 --- a/lib/build.js +++ b/lib/build.js @@ -1,6 +1,5 @@ 'use babel'; -import child_process from 'child_process'; import fs from 'fs'; import path from 'path'; import _ from 'lodash'; @@ -81,7 +80,7 @@ module.exports = { } }, - activate: function() { + activate: function () { // Manually append /usr/local/bin as it may not be set on some systems, // and it's common to have node installed here. Keep it at end so it won't // accidentially override any other node installation @@ -129,7 +128,7 @@ module.exports = { }); this.errorMatcher.on('match', (text, id) => { - let callback = this.errorMatcher.goto.bind(this.errorMatcher, id); + const callback = this.errorMatcher.goto.bind(this.errorMatcher, id); this.buildView.link(text, id, callback); }); @@ -137,13 +136,13 @@ module.exports = { let projectPaths = atom.project.getPaths(); atom.project.onDidChangePaths(() => { - let addedPaths = atom.project.getPaths().filter(el => projectPaths.indexOf(el) === -1); + const addedPaths = atom.project.getPaths().filter(el => projectPaths.indexOf(el) === -1); this.refreshTargets(addedPaths); projectPaths = atom.project.getPaths(); }); }, - deactivate: function() { + deactivate: function () { tools.forEach(tool => { if (tool.off) { _.forEach(tool.ctx, ctx => tool.off.apply(ctx, [ 'refresh' ])); @@ -158,7 +157,7 @@ module.exports = { }, activePath: function () { - let textEditor = atom.workspace.getActiveTextEditor(); + const textEditor = atom.workspace.getActiveTextEditor(); if (!textEditor || !textEditor.getPath()) { /* default to building the first one if no editor is active */ if (0 === atom.project.getPaths().length) { @@ -166,47 +165,47 @@ module.exports = { } return atom.project.getPaths()[0]; - } else { - /* otherwise, build the one in the root of the active editor */ - return atom.project.getPaths().sort((a, b) => (b.length - a.length)).find(path => { - let realpath = fs.realpathSync(path); - return textEditor.getPath().substr(0, realpath.length) === realpath; - }); } + + /* otherwise, build the one in the root of the active editor */ + return atom.project.getPaths().sort((a, b) => (b.length - a.length)).find(p => { + const realpath = fs.realpathSync(p); + return textEditor.getPath().substr(0, realpath.length) === realpath; + }); }, - cmdDefaults: function (path) { + cmdDefaults: function (cwd) { return { env: {}, args: [], - cwd: path, + cwd: cwd, sh: true, errorMatch: '', dispose: Function.prototype }; }, - refreshTargets: function(refreshPaths) { + refreshTargets: function (refreshPaths) { refreshPaths = refreshPaths || atom.project.getPaths(); - let pathPromise = refreshPaths.map((path) => { - this.targetsLoading[path] = true; - this.targets[path] = this.targets[path] || []; - let settingsPromise = tools.filter((tool) => { + const pathPromise = refreshPaths.map((p) => { + this.targetsLoading[p] = true; + this.targets[p] = this.targets[p] || []; + const settingsPromise = tools.filter((tool) => { tool.ctx = tool.ctx || []; - tool.ctx[path] = tool.ctx[path] || {}; - return tool.isEligable.apply(tool.ctx[path], [ path ]); + tool.ctx[p] = tool.ctx[p] || {}; + return tool.isEligable.apply(tool.ctx[p], [ p ]); }).map((tool) => { GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); if (tool.on) { - tool.off.apply(tool.ctx[path], [ 'refresh' ]); - tool.on.apply(tool.ctx[path], [ 'refresh', this.refreshTargets.bind(this, [ path ]) ]); + tool.off.apply(tool.ctx[p], [ 'refresh' ]); + tool.on.apply(tool.ctx[p], [ 'refresh', this.refreshTargets.bind(this, [ p ]) ]); } return Promise.resolve().then(() => { - return tool.settings.apply(tool.ctx[path], [ path ]); - }).catch(function (err) { + return tool.settings.apply(tool.ctx[p], [ p ]); + }).catch((err) => { if (err instanceof SyntaxError) { atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + err.message, @@ -223,15 +222,15 @@ module.exports = { return Promise.all(settingsPromise).then((settings) => { settings = [].concat.apply([], settings).filter(Boolean).map(setting => - _.defaults(setting, this.cmdDefaults(path)) + _.defaults(setting, this.cmdDefaults(p)) ); - if (_.isNull(this.activeTarget[path]) || !settings.find(s => s.name === this.activeTarget[path])) { + if (_.isNull(this.activeTarget[p]) || !settings.find(s => s.name === this.activeTarget[p])) { /* Active target has been removed or not set. Set it to the highest prio target */ - this.activeTarget[path] = settings[0] ? settings[0].name : undefined; + this.activeTarget[p] = settings[0] ? settings[0].name : undefined; } - this.targets[path].forEach(target => target.dispose()); + this.targets[p].forEach(target => target.dispose()); settings.forEach((setting, index) => { if (!setting.keymap) { @@ -239,19 +238,19 @@ module.exports = { } GoogleAnalytics.sendEvent('keymap', 'registered', setting.keymap); - let commandName = 'build:trigger:' + setting.name; - let keymapSpec = { 'atom-workspace': {} }; + const commandName = 'build:trigger:' + setting.name; + const keymapSpec = { 'atom-workspace': {} }; keymapSpec['atom-workspace'][setting.keymap] = commandName; - let keymapDispose = atom.keymaps.add(setting.name, keymapSpec); - let commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); + const keymapDispose = atom.keymaps.add(setting.name, keymapSpec); + const commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); settings[index].dispose = () => { keymapDispose.dispose(); commandDispose.dispose(); }; }); - this.targets[path] = settings; - this.targetsLoading[path] = false; + this.targets[p] = settings; + this.targetsLoading[p] = false; }); }); @@ -260,41 +259,41 @@ module.exports = { return; } - let rows = refreshPaths.map(path => `${this.targets[path].length} targets at: ${path}`); + const rows = refreshPaths.map(p => `${this.targets[p].length} targets at: ${p}`); atom.notifications.addInfo('Build targets parsed.', { detail: rows.join('\n') }); }); }, - selectActiveTarget: function() { - let path = this.activePath(); - let targets = this.targets[path]; - let targetsView = new TargetsView(); + selectActiveTarget: function () { + const p = this.activePath(); + const targets = this.targets[p]; + const targetsView = new TargetsView(); - if (this.targetsLoading[path]) { + if (this.targetsLoading[p]) { return targetsView.setLoading('Loading project build targets\u2026'); } - targetsView.setActiveTarget(this.activeTarget[path]); + targetsView.setActiveTarget(this.activeTarget[p]); targetsView.setItems((targets || []).map(target => target.name)); targetsView.awaitSelection().then((newTarget) => { - this.activeTarget[path] = newTarget; + this.activeTarget[p] = newTarget; - let workspaceElement = atom.views.getView(atom.workspace); + const workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); }).catch((err) => targetsView.setError(err.message)); }, - replace: function(value, targetEnv) { - let env = _.extend(_.clone(process.env), targetEnv); - value = value.replace(/\$(\w+)/g, function(match, name) { + replace: function (value, targetEnv) { + const env = _.extend({}, process.env, targetEnv); + value = value.replace(/\$(\w+)/g, function (match, name) { return name in env ? env[name] : match; }); - let editor = atom.workspace.getActiveTextEditor(); + const editor = atom.workspace.getActiveTextEditor(); - let projectPaths = _.map(atom.project.getPaths(), (projectPath) => { + const projectPaths = _.map(atom.project.getPaths(), (projectPath) => { try { return fs.realpathSync(projectPath); } catch (e) { /* Do nothing. */ } @@ -302,11 +301,9 @@ module.exports = { let projectPath = projectPaths[0]; if (editor && 'untitled' !== editor.getTitle()) { - let activeFile = fs.realpathSync(editor.getPath()); - let activeFilePath = path.dirname(activeFile); - projectPath = _.find(projectPaths, function(projectPath) { - return activeFilePath && activeFilePath.startsWith(projectPath); - }); + const activeFile = fs.realpathSync(editor.getPath()); + const activeFilePath = path.dirname(activeFile); + projectPath = _.find(projectPaths, (p) => activeFilePath && activeFilePath.startsWith(p)); value = value.replace(/{FILE_ACTIVE}/g, activeFile); value = value.replace(/{FILE_ACTIVE_PATH}/g, activeFilePath); value = value.replace(/{FILE_ACTIVE_NAME}/g, path.basename(activeFile)); @@ -320,32 +317,32 @@ module.exports = { return value; }, - startNewBuild: function(source, targetName) { - let path = this.activePath(); - targetName = targetName || this.activeTarget[path]; + startNewBuild: function (source, targetName) { + const p = this.activePath(); + targetName = targetName || this.activeTarget[p]; - Promise.resolve(this.targets[path]).then(targets => { + Promise.resolve(this.targets[p]).then(targets => { if (!targets) { throw new BuildError('No eligible build target.', 'No configuration to build this project exists.'); } - let target = targets.find(target => target.name === targetName); + const target = targets.find(t => t.name === targetName); GoogleAnalytics.sendEvent('build', 'triggered'); if (!target.exec) { - throw new BuildError('Inavlid build file.', 'No executable command specified.'); + throw new BuildError('Invalid build file.', 'No executable command specified.'); } - let env = _.extend({}, process.env, target.env); + const env = _.extend({}, process.env, target.env); _.forEach(env, (value, key, list) => { list[key] = this.replace(value, target.env); }); - let exec = this.replace(target.exec, target.env); - let args = target.args.map(arg => this.replace(arg, target.env)); - let cwd = this.replace(target.cwd, target.env); + const exec = this.replace(target.exec, target.env); + const args = target.args.map(arg => this.replace(arg, target.env)); + const cwd = this.replace(target.cwd, target.env); - this.child = child_process.spawn( + this.child = require('child_process').spawn( target.sh ? '/bin/sh' : exec, target.sh ? [ '-c', [ exec ].concat(args).join(' ') ] : args, { cwd: cwd, env: env } @@ -378,7 +375,7 @@ module.exports = { this.child.on('close', (exitCode) => { this.errorMatcher.set(target.errorMatch, cwd, this.buildView.output.text()); - let success = 0 === exitCode && !this.errorMatcher.hasMatch(); + const success = (0 === exitCode) && !this.errorMatcher.hasMatch(); this.buildView.buildFinished(success); if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); @@ -404,11 +401,13 @@ module.exports = { } atom.notifications.addWarning(err.name, { detail: err.message }); + } else { + atom.notifications.addError('Failed to build.', { detail: err.message }); } }); }, - abort: function(cb) { + abort: function (cb) { this.child.removeAllListeners('close'); this.child.on('close', () => { this.child = null; @@ -424,17 +423,17 @@ module.exports = { this.child.killed = true; }, - build: function(source, event) { + build: function (source, event) { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), () => { - let next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); + const next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); this.child ? this.abort(next) : next(); }); }, - doSaveConfirm: function(modifiedTextEditors, continuecb, cancelcb) { - let saveAndContinue = (save) => { + doSaveConfirm: function (modifiedTextEditors, continuecb, cancelcb) { + const saveAndContinue = (save) => { modifiedTextEditors.forEach((textEditor) => save && textEditor.save()); continuecb(); }; @@ -451,14 +450,13 @@ module.exports = { this.saveConfirmView.show(saveAndContinue, cancelcb); }, - unsavedTextEditors: function() { + unsavedTextEditors: function () { return atom.workspace.getTextEditors().filter((textEditor) => { return textEditor.isModified() && ('untitled' !== textEditor.getTitle()); }); }, - stop: function() { - + stop: function () { clearTimeout(this.finishedTimer); if (this.child) { if (this.child.killed) { diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 2ad23910..86445c9d 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; -import { XRegExp } from 'xregexp'; +import { XRegExp } from 'XRegExp'; import { EventEmitter } from 'events'; import GoogleAnalytics from './google-analytics'; @@ -30,7 +30,7 @@ export default class ErrorMatcher extends EventEmitter { } goto(id) { - let match = this.currentMatch.find(m => m.id === id); + const match = this.currentMatch.find(m => m.id === id); if (!match) { return this.emit('error', 'Can\'t find match with id ' + id); } @@ -50,8 +50,8 @@ export default class ErrorMatcher extends EventEmitter { file = this.cwd + path.sep + file; } - let row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ - let col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ + const row = match.line ? match.line - 1 : 0; /* Because atom is zero-based */ + const col = match.col ? match.col - 1 : 0; /* Because atom is zero-based */ fs.exists(file, (exists) => { if (!exists) { @@ -68,8 +68,8 @@ export default class ErrorMatcher extends EventEmitter { _parse() { this.currentMatch = []; - let self = this; - let matchFunction = function (match, i, string, regex) { + const self = this; + const matchFunction = function (match, i, string, regex) { match.id = 'error-match-' + self.regex.indexOf(regex) + '-' + i; this.push(match); }; diff --git a/lib/google-analytics.js b/lib/google-analytics.js index babf0461..98516a87 100644 --- a/lib/google-analytics.js +++ b/lib/google-analytics.js @@ -2,23 +2,22 @@ import _ from 'lodash'; import querystring from 'querystring'; -let cid; export default class GoogleAnalytics { static getCid(cb) { - if (cid) { - return cb(cid); + if (this.cid) { + return cb(this.cid); } require('getmac').getMac((error, macAddress) => { return error ? - cb(cid = require('node-uuid').v4()) : - cb(require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex')); + cb(this.cid = require('node-uuid').v4()) : + cb(this.cid = require('crypto').createHash('sha1').update(macAddress, 'utf8').digest('hex')); }); } static sendEvent(category, action, label, value) { - let params = { + const params = { t: 'event', ec: category, ea: action @@ -53,7 +52,7 @@ export default class GoogleAnalytics { } static post(url) { - let xhr = new XMLHttpRequest(); + const xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.send(null); } @@ -69,7 +68,7 @@ export default class GoogleAnalytics { atom.packages.onDidActivatePackage((pkg) => { if ('metrics' === pkg.name) { - let buildPackage = atom.packages.getLoadedPackage('build'); + const buildPackage = atom.packages.getLoadedPackage('build'); GoogleAnalytics.sendEvent('core', 'activated', buildPackage.metadata.version); } }); diff --git a/lib/targets-view.js b/lib/targets-view.js index ebdc8a03..06794312 100644 --- a/lib/targets-view.js +++ b/lib/targets-view.js @@ -27,7 +27,7 @@ export default class TargetsView extends SelectListView { setItems() { super.setItems(...arguments); - var activeItemView = this.find('.active'); + const activeItemView = this.find('.active'); if (0 < activeItemView.length) { this.selectItemView(activeItemView); this.scrollToItemView(activeItemView); @@ -39,9 +39,9 @@ export default class TargetsView extends SelectListView { } viewForItem(targetName) { - var activeTarget = this.activeTarget; - return TargetsView.render(function() { - var activeClass = (targetName === activeTarget ? 'active' : ''); + const activeTarget = this.activeTarget; + return TargetsView.render(function () { + const activeClass = (targetName === activeTarget ? 'active' : ''); this.li({ class: activeClass + ' build-target' }, targetName); }); } diff --git a/package.json b/package.json index 2f882687..4b8e6b47 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "atom-build-spec-helpers": "^0.3.0", "babel-eslint": "^4.1.5", "eslint": "^1.10.1", + "eslint-config-airbnb": "^1.0.0", + "eslint-plugin-react": "^3.10.0", "fs-extra": "^0.23.0", "temp": "^0.8.1" }, diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index a0c3b69f..e4f55f8e 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -1,17 +1,17 @@ 'use babel'; -var _ = require('lodash'); -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); +const _ = require('lodash'); +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); -describe('Confirm', function() { - var directory = null; - var workspaceElement = null; +describe('Confirm', () => { + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.setPaths([ directory ]); @@ -22,87 +22,87 @@ describe('Confirm', function() { jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - runs(function() { + runs(() => { workspaceElement = atom.views.getView(atom.workspace); jasmine.attachToDOM(workspaceElement); }); - waitsForPromise(function() { + waitsForPromise(() => { return atom.packages.activatePackage('build'); }); }); - afterEach(function() { + afterEach(() => { fs.removeSync(directory); }); - describe('when the text editor is modified', function() { - it('should show the save confirmation', function() { + describe('when the text editor is modified', () => { + it('should show the save confirmation', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - waitsForPromise(function() { + waitsForPromise(() => { return atom.workspace.open('.atom-build.json'); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.insertText('hello kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector(':focus'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.btn-success:focus')).toExist(); }); }); - it('should cancel the confirm window when pressing escape', function() { + it('should cancel the confirm window when pressing escape', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - waitsForPromise(function() { + waitsForPromise(() => { return atom.workspace.open('.atom-build.json'); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.insertText('hello kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector(':focus'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:no-confirm'); expect(workspaceElement.querySelector('.btn-success:focus')).not.toExist(); }); }); - it('should not do anything if issuing no-confirm whithout the dialog', function () { + it('should not do anything if issuing no-confirm whithout the dialog', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); atom.commands.dispatch(workspaceElement, 'build:no-confirm'); }); - it('should not confirm if a TextEditor edits an unsaved file', function() { + it('should not confirm if a TextEditor edits an unsaved file', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('.atom-build.json'), @@ -110,26 +110,26 @@ describe('Confirm', function() { ]); }); - runs(function() { - var editor = _.find(atom.workspace.getTextEditors(), function(textEditor) { + runs(() => { + const editor = _.find(atom.workspace.getTextEditors(), (textEditor) => { return ('untitled' === textEditor.getTitle()); }); editor.insertText('Just some temporary place to write stuff'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); - it('should save and build when selecting save and build', function() { + it('should save and build when selecting save and build', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); @@ -137,15 +137,15 @@ describe('Confirm', function() { cmd: 'cat catme' })); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('catme') ]); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.setText('kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -154,20 +154,20 @@ describe('Confirm', function() { runs(() => workspaceElement.querySelector(':focus').click()); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/kansas/); expect(!editor.isModified()); }); }); - it('should build but not save when opting so', function() { + it('should build but not save when opting so', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); @@ -175,41 +175,41 @@ describe('Confirm', function() { cmd: 'cat catme' })); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('catme') ]); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.setText('catme'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector(':focus'); }); - runs(function() { + runs(() => { workspaceElement.querySelector('button[click="confirmWithoutSave"]').click(); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').innerHTML).not.toMatch(/kansas/); expect(editor.isModified()); }); }); - it('should do nothing when cancelling', function() { + it('should do nothing when cancelling', () => { expect(workspaceElement.querySelector('.build-confirm')).not.toExist(); fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); @@ -217,31 +217,31 @@ describe('Confirm', function() { cmd: 'cat catme' })); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('catme') ]); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.setText('kansas'); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector(':focus'); }); - runs(function() { + runs(() => { workspaceElement.querySelector('button[click="cancel"]').click(); }); waits(2); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); expect(workspaceElement.querySelector('.build')).not.toExist(); expect(editor.isModified()); }); @@ -256,32 +256,32 @@ describe('Confirm', function() { cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('.atom-build.json') ]); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.setText(JSON.stringify({ cmd: 'echo kansas' })); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build-confirm'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); waits(200); // Everything is the same so we can't know when second build:trigger has been handled - runs(function () { + runs(() => { expect(workspaceElement.querySelectorAll('.build-confirm').length).toEqual(1); }); }); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 1af75fe0..c16bcceb 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,24 +1,24 @@ 'use babel'; -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); - -describe('Error Match', function() { - var errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; - var errorMatchNoFileBuildFile = __dirname + '/fixture/.atom-build.error-match-no-file.json'; - var errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; - var errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json'; - var errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; - var errorMatchLongOutputAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-long-output.json'; - var errorMatchMultiMatcherAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-errorMatch.json'; - - var directory = null; - var workspaceElement = null; +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); + +describe('Error Match', () => { + const errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; + const errorMatchNoFileBuildFile = __dirname + '/fixture/.atom-build.error-match-no-file.json'; + const errorMatchNLCAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-no-line-col.json'; + const errorMatchMultiAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple.json'; + const errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; + const errorMatchLongOutputAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-long-output.json'; + const errorMatchMultiMatcherAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-errorMatch.json'; + + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.setPaths([ directory ]); @@ -31,23 +31,22 @@ describe('Error Match', function() { jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - runs(function() { + runs(() => { workspaceElement = atom.views.getView(atom.workspace); jasmine.attachToDOM(workspaceElement); }); - waitsForPromise(function() { + waitsForPromise(() => { return atom.packages.activatePackage('build'); }); }); - afterEach(function() { + afterEach(() => { fs.removeSync(directory); }); - describe('when error matcher is configured incorrectly', function () { - it('should show an error if regex is invalid', function () { - + describe('when error matcher is configured incorrectly', () => { + it('should show an error if regex is invalid', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'return 1', errorMatch: '(invalidRegex' @@ -57,15 +56,15 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { expect(atom.notifications.getNotifications().length).toEqual(1); - var notification = atom.notifications.getNotifications()[0]; + const notification = atom.notifications.getNotifications()[0]; expect(notification.getType()).toEqual('error'); expect(notification.getMessage()).toEqual('Error matching failed!'); expect(notification.options.detail).toMatch(/Unterminated group/); @@ -73,8 +72,8 @@ describe('Error Match', function() { }); }); - describe('when output is captured to show editor on error', function () { - it('should place the line and column on error in correct file', function () { + describe('when output is captured to show editor on error', () => { + it('should place the line and column on error in correct file', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); @@ -83,29 +82,29 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); }); }); - it('should give an error if matched file does not exist', function () { + it('should give an error if matched file does not exist', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNoFileBuildFile)); @@ -114,27 +113,27 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.notifications.getNotifications().length > 0; }); - runs(function() { - var notification = atom.notifications.getNotifications()[0]; + runs(() => { + const notification = atom.notifications.getNotifications()[0]; expect(notification.getType()).toEqual('error'); expect(notification.getMessage()).toEqual('Error matching failed!'); }); }); - it('should open just the file if line and column is not available', function () { + it('should open just the file if line and column is not available', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchNLCAtomBuildFile)); @@ -143,26 +142,26 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); expect(editor.getTitle()).toEqual('.atom-build.json'); }); }); - it('should cycle through the file if multiple error occurred', function () { + it('should cycle through the file if multiple error occurred', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiAtomBuildFile)); @@ -171,63 +170,63 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); atom.workspace.getActivePane().destroyActiveItem(); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(1); expect(bufferPosition.column).toEqual(4); atom.workspace.getActivePane().destroyActiveItem(); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); }); }); - it('should jump to first error', function () { + it('should jump to first error', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiFirstAtomBuildFile)); @@ -236,63 +235,63 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); atom.workspace.getActivePane().destroyActiveItem(); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(1); expect(bufferPosition.column).toEqual(4); atom.workspace.getActivePane().destroyActiveItem(); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); }); }); - it('should open the the file even if tool gives absolute path', function () { + it('should open the the file even if tool gives absolute path', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo __' + directory + '.atom-build.json__ && return 1', errorMatch: '__(?.+)__' @@ -302,27 +301,27 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { return atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); - waitsFor(function () { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); expect(editor.getPath()).toEqual(directory + '.atom-build.json'); }); }); - it('should prepend `cwd` to the relative matched file if set', function () { - var atomBuild = { + it('should prepend `cwd` to the relative matched file if set', () => { + const atomBuild = { cmd: 'echo __.atom-build.json__ && exit 1', cwd: directory, errorMatch: '__(?.+)__' @@ -333,43 +332,43 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function () { + runs(() => { return atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); - waitsFor(function () { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function () { + runs(() => { // Error match one more time to make sure `cwd` isn't prepended multiple times atom.workspace.getActivePaneItem().destroy(); }); - waitsFor(function () { + waitsFor(() => { return !atom.workspace.getActiveTextEditor(); }); - runs(function () { + runs(() => { return atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); - waitsFor(function () { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function () { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); expect(editor.getPath()).toEqual(directory + '.atom-build.json'); }); }); - it('should auto match error on failed build when config is set', function () { + it('should auto match error on failed build when config is set', () => { atom.config.set('build.scrollOnError', true); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchAtomBuildFile)); @@ -378,25 +377,25 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - waitsFor(function () { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); }); }); - it('should scroll the build panel to the text of the error', function () { + it('should scroll the build panel to the text of the error', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); @@ -404,36 +403,36 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); let firstScrollTop; - runs(function() { + runs(() => { firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); - runs(function() { + runs(() => { /* Should wrap around to first match */ expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); }); }); - it('match-first should scroll the build panel', function () { + it('match-first should scroll the build panel', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchLongOutputAtomBuildFile)); @@ -441,35 +440,35 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); let firstScrollTop; - runs(function() { + runs(() => { firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(100); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); waits(100); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); }); }); - it('should match multiple regexes in the correct order', function () { + it('should match multiple regexes in the correct order', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(errorMatchMultiMatcherAtomBuildFile)); @@ -478,56 +477,56 @@ describe('Error Match', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(2); expect(bufferPosition.column).toEqual(7); atom.workspace.getActivePane().destroyActiveItem(); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(0); expect(bufferPosition.column).toEqual(1); atom.workspace.getActivePane().destroyActiveItem(); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waitsFor(function() { + waitsFor(() => { return atom.workspace.getActiveTextEditor(); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); - var bufferPosition = editor.getCursorBufferPosition(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); + const bufferPosition = editor.getCursorBufferPosition(); expect(editor.getTitle()).toEqual('.atom-build.json'); expect(bufferPosition.row).toEqual(1); expect(bufferPosition.column).toEqual(4); diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index e5948773..061699f8 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -1,16 +1,16 @@ 'use babel'; -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); -describe('Keymap', function() { - var directory = null; - var workspaceElement = null; +describe('Keymap', () => { + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.setPaths([ directory ]); @@ -21,23 +21,22 @@ describe('Keymap', function() { jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - runs(function() { + runs(() => { workspaceElement = atom.views.getView(atom.workspace); jasmine.attachToDOM(workspaceElement); }); - waitsForPromise(function() { + waitsForPromise(() => { return atom.packages.activatePackage('build'); }); }); - afterEach(function() { + afterEach(() => { fs.removeSync(directory); }); - describe('when custom keymap is defined in .atom-build.json', function () { - it('should trigger the build when that key combination is pressed', function () { - + describe('when custom keymap is defined in .atom-build.json', () => { + it('should trigger the build when that key combination is pressed', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ name: 'The default build', cmd: 'echo default', @@ -53,36 +52,35 @@ describe('Keymap', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); - waitsFor(function() { + waitsFor(() => { return !workspaceElement.querySelector('.build .title'); }); - runs(function () { + runs(() => { specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); }); }); - it('should not changed the set active build', function () { - + it('should not changed the set active build', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ name: 'The default build', cmd: 'echo default', @@ -98,54 +96,54 @@ describe('Keymap', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); - waitsFor(function() { + waitsFor(() => { return !workspaceElement.querySelector('.build .title'); }); - runs(function () { + runs(() => { specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); - waitsFor(function() { + waitsFor(() => { return !workspaceElement.querySelector('.build .title'); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); }); - it('should dispose keymap when reloading targets', function () { + it('should dispose keymap when reloading targets', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ name: 'The default build', cmd: 'echo default', @@ -161,30 +159,30 @@ describe('Keymap', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); - waitsFor(function() { + waitsFor(() => { return !workspaceElement.querySelector('.build .title'); }); - runs(function () { + runs(() => { specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -201,27 +199,27 @@ describe('Keymap', function() { waitsForPromise(() => specHelpers.awaitTargets()); - waitsFor(function() { + waitsFor(() => { return !workspaceElement.querySelector('.build .title'); }); - runs(function () { + runs(() => { specHelpers.keydown('k', { ctrl: true, alt: true, element: workspaceElement }); }); waits(300); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); specHelpers.keydown('x', { ctrl: true, element: workspaceElement }); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/ctrl-x new file/); }); }); diff --git a/spec/build-spec.js b/spec/build-spec.js index 5e577e2a..d1313ef5 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,24 +1,24 @@ 'use babel'; -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); - -describe('Build', function() { - var goodAtomBuildfile = __dirname + '/fixture/.atom-build.json'; - var shellAtomBuildfile = __dirname + '/fixture/.atom-build.shell.json'; - var replaceAtomBuildFile = __dirname + '/fixture/.atom-build.replace.json'; - var shFalseAtomBuildFile = __dirname + '/fixture/.atom-build.sh-false.json'; - var shTrueAtomBuildFile = __dirname + '/fixture/.atom-build.sh-true.json'; - var shDefaultAtomBuildFile = __dirname + '/fixture/.atom-build.sh-default.json'; - var syntaxErrorAtomBuildFile = __dirname + '/fixture/.atom-build.syntax-error.json'; - - var directory = null; - var workspaceElement = null; +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); + +describe('Build', () => { + const goodAtomBuildfile = __dirname + '/fixture/.atom-build.json'; + const shellAtomBuildfile = __dirname + '/fixture/.atom-build.shell.json'; + const replaceAtomBuildFile = __dirname + '/fixture/.atom-build.replace.json'; + const shFalseAtomBuildFile = __dirname + '/fixture/.atom-build.sh-false.json'; + const shTrueAtomBuildFile = __dirname + '/fixture/.atom-build.sh-true.json'; + const shDefaultAtomBuildFile = __dirname + '/fixture/.atom-build.sh-default.json'; + const syntaxErrorAtomBuildFile = __dirname + '/fixture/.atom-build.syntax-error.json'; + + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); @@ -30,10 +30,10 @@ describe('Build', function() { jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - waitsForPromise(function() { - return specHelpers.vouch(temp.mkdir, 'atom-build-spec-').then(function (dir) { + waitsForPromise(() => { + return specHelpers.vouch(temp.mkdir, 'atom-build-spec-').then( (dir) => { return specHelpers.vouch(fs.realpath, dir); - }).then(function (dir) { + }).then( (dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); return atom.packages.activatePackage('build'); @@ -41,18 +41,18 @@ describe('Build', function() { }); }); - afterEach(function() { + afterEach(() => { fs.removeSync(directory); }); - describe('when package is activated', function() { - it('should not show build window if panelVisibility is Toggle ', function() { + describe('when package is activated', () => { + it('should not show build window if panelVisibility is Toggle ', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); - describe('when building', function () { - it('should show build failed if build fails', function() { + describe('when building', () => { + fit('should show build failed if build fails', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -63,18 +63,18 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); }); }); - it('should fail build, if errors are matched', function() { + it('should fail build, if errors are matched', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -86,13 +86,13 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); }); - it('should cancel build when stopping it, and remove when stopping again', function() { + it('should cancel build when stopping it, and remove when stopping again', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -106,27 +106,27 @@ describe('Build', function() { // Let build run for one second before we terminate it waits(1000); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Building, this will take some time.../); atom.commands.dispatch(workspaceElement, 'build:stop'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:stop'); }); - waitsFor(function() { - return (workspaceElement.querySelector('.build .title .title-text').textContent == 'Aborted!'); + waitsFor(() => { + return (workspaceElement.querySelector('.build .title .title-text').textContent === 'Aborted!'); }); }); - it('should not show the build panel if no build file exists', function() { + it('should not show the build panel if no build file exists', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.commands.dispatch(workspaceElement, 'build:trigger'); @@ -134,14 +134,14 @@ describe('Build', function() { /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ waits(200); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); }); - describe('when build is triggered twice', function() { - it('should not leave multiple panels behind', function() { + describe('when build is triggered twice', () => { + it('should not leave multiple panels behind', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); @@ -154,11 +154,11 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); @@ -166,14 +166,14 @@ describe('Build', function() { /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ waits(200); - runs(function() { + runs(() => { expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1); }); }); }); - describe('when custom .atom-build.json is available', function() { - it('should show the build window', function() { + describe('when custom .atom-build.json is available', () => { + it('should show the build window', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); @@ -182,18 +182,18 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); }); }); - it('should be possible to exec shell commands with wildcard expansion', function() { + it('should be possible to exec shell commands with wildcard expansion', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shellAtomBuildfile)); @@ -202,18 +202,18 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Good news, everyone!/); }); }); - it('should show sh message if sh is true', function() { + it('should show sh message if sh is true', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shTrueAtomBuildFile)); @@ -222,18 +222,18 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing with sh:/); }); }); - it('should not show sh message if sh is false', function() { + it('should not show sh message if sh is false', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shFalseAtomBuildFile)); @@ -242,18 +242,18 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing:/); }); }); - it('should show sh message if sh is unspecified', function() { + it('should show sh message if sh is unspecified', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shDefaultAtomBuildFile)); @@ -262,18 +262,18 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing with sh:/); }); }); - it('should show graphical error message if build-file contains syntax errors', function() { + it('should show graphical error message if build-file contains syntax errors', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(syntaxErrorAtomBuildFile)); @@ -282,19 +282,19 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return atom.notifications.getNotifications().length > 0; }); - runs(function() { - var notification = atom.notifications.getNotifications()[0]; + runs(() => { + const notification = atom.notifications.getNotifications()[0]; expect(notification.getType()).toEqual('error'); expect(notification.getMessage()).toEqual('Invalid build file.'); expect(notification.options.detail).toMatch(/Unexpected token t/); }); }); - it('should not cache the contents of the build file', function () { + it('should not cache the contents of the build file', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -305,20 +305,20 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/first/); }); - waitsFor(function () { + waitsFor(() => { return !workspaceElement.querySelector('.build .title'); }); - runs(function () { + runs(() => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo second' })); @@ -326,30 +326,29 @@ describe('Build', function() { waits(100); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/second/); }); }); }); - describe('when replacements are specified in the atom-build.json file', function() { - it('should replace those with their dynamic value', function() { - + describe('when replacements are specified in the atom-build.json file', () => { + it('should replace those with their dynamic value', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); process.env.FROM_PROCESS_ENV = '{FILE_ACTIVE}'; fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(replaceAtomBuildFile)); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('.atom-build.json') @@ -358,14 +357,14 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - var output = workspaceElement.querySelector('.build .output').textContent; + const output = workspaceElement.querySelector('.build .output').textContent; expect(output.indexOf('PROJECT_PATH=' + directory.substring(0, -1))).not.toBe(-1); expect(output.indexOf('FILE_ACTIVE=' + directory + '.atom-build.json')).not.toBe(-1); @@ -377,113 +376,113 @@ describe('Build', function() { }); }); - describe('when the text editor is saved', function() { - it('should build when buildOnSave is true', function() { + describe('when the text editor is saved', () => { + it('should build when buildOnSave is true', () => { atom.config.set('build.buildOnSave', true); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo Surprising is the passing of time but not so, as the time of passing.' })); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('dummy') ]); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.save(); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); - it('should not build when buildOnSave is false', function() { + it('should not build when buildOnSave is false', () => { atom.config.set('build.buildOnSave', false); fs.writeFileSync(directory + '.atom-build.json', { cmd: 'echo "hello, world"' }); - waitsForPromise(function() { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open('dummy') ]); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.save(); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); - it('should not attempt to build if buildOnSave is true and no build tool exists', function () { + it('should not attempt to build if buildOnSave is true and no build tool exists', () => { atom.config.set('build.buildOnSave', true); - waitsForPromise(function() { + waitsForPromise(() => { return atom.workspace.open('dummy'); }); - runs(function() { - var editor = atom.workspace.getActiveTextEditor(); + runs(() => { + const editor = atom.workspace.getActiveTextEditor(); editor.save(); }); waits(200); - runs(function() { + runs(() => { expect(atom.notifications.getNotifications().length).toEqual(0); }); }); }); - describe('when multiple project roots are open', function () { - it('should run the second root if a file there is active', function () { - var directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + describe('when multiple project roots are open', () => { + it('should run the second root if a file there is active', () => { + const directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.addPath(directory2); expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); - waitsForPromise(function () { + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), atom.workspace.open(directory2 + '/main.c') ]); }); - runs(function() { + runs(() => { atom.workspace.getActiveTextEditor().save(); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); }); }); - it('should scan new project roots when they are added', function () { - var directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + it('should scan new project roots when they are added', () => { + const directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); atom.project.addPath(directory2); @@ -498,20 +497,20 @@ describe('Build', function() { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); }); }); }); - describe('when build panel is toggled and it is not visible', function() { - it('should show the build panel', function() { + describe('when build panel is toggled and it is not visible', () => { + it('should show the build panel', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); @@ -520,8 +519,8 @@ describe('Build', function() { }); }); - describe('when build is triggered, focus should adhere the stealFocus config', function () { - it('should focus the build panel if stealFocus is true', function () { + describe('when build is triggered, focus should adhere the stealFocus config', () => { + it('should focus the build panel if stealFocus is true', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); @@ -530,20 +529,20 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build'); }); - runs(function() { + runs(() => { expect(document.activeElement).toHaveClass('build'); }); }); - it('should leave focus untouched if stealFocus is false', function () { + it('should leave focus untouched if stealFocus is false', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.config.set('build.stealFocus', false); - var activeElement = document.activeElement; + const activeElement = document.activeElement; fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); @@ -551,28 +550,28 @@ describe('Build', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build'); }); - runs(function() { + runs(() => { expect(document.activeElement).toEqual(activeElement); expect(document.activeElement).not.toHaveClass('build'); }); }); }); - describe('when no build tools are available', function () { - it('should show a warning', function () { + describe('when no build tools are available', () => { + it('should show a warning', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.commands.dispatch(workspaceElement, 'build:trigger'); - waitsFor(function() { + waitsFor(() => { return atom.notifications.getNotifications().length > 0; }); - runs(function() { - var notification = atom.notifications.getNotifications()[0]; + runs(() => { + const notification = atom.notifications.getNotifications()[0]; expect(notification.getType()).toEqual('warning'); expect(notification.getMessage()).toEqual('No eligible build target.'); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 24c819f1..11e0acf7 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -1,17 +1,17 @@ 'use babel'; -var _ = require('lodash'); -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); +const _ = require('lodash'); +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); -describe('Target', function() { - var directory = null; - var workspaceElement = null; +describe('Target', () => { + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { workspaceElement = atom.views.getView(atom.workspace); atom.config.set('build.buildOnSave', false); @@ -22,10 +22,10 @@ describe('Target', function() { jasmine.unspy(window, 'clearTimeout'); jasmine.attachToDOM(workspaceElement); - waitsForPromise(function() { - return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then(function (dir) { + waitsForPromise(() => { + return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then((dir) => { return specHelpers.vouch(fs.realpath, dir); - }).then(function (dir) { + }).then((dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); return atom.packages.activatePackage('build'); @@ -33,158 +33,157 @@ describe('Target', function() { }); }); - afterEach(function() { + afterEach(() => { fs.removeSync(directory); }); - describe('when multiple targets exists', function () { - - it('should list those targets in a SelectListView (from .atom-build.json)', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/.atom-build.targets.json'; + describe('when multiple targets exists', () => { + it('should list those targets in a SelectListView (from .atom-build.json)', () => { + waitsForPromise(() => { + const file = __dirname + '/fixture/.atom-build.targets.json'; return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') .then(() => specHelpers.refreshAwaitTargets()); }); waitsForPromise(() => specHelpers.refreshAwaitTargets()); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:select-active-target'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.select-list li.build-target'); }); - runs(function () { - var targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), el => el.textContent); + runs(() => { + const targets = _.map(workspaceElement.querySelectorAll('.select-list li.build-target'), el => el.textContent); expect(targets).toEqual([ 'Custom: The default build', 'Custom: Some customized build' ]); }); }); - it('should mark the first target as active', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/.atom-build.targets.json'; + it('should mark the first target as active', () => { + waitsForPromise(() => { + const file = __dirname + '/fixture/.atom-build.targets.json'; return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') .then(() => specHelpers.refreshAwaitTargets()); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:select-active-target'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.select-list li.build-target'); }); - runs(function () { - var el = workspaceElement.querySelector('.select-list li.build-target'); // querySelector selects the first element + runs(() => { + const el = workspaceElement.querySelector('.select-list li.build-target'); // querySelector selects the first element expect(el).toHaveClass('selected'); expect(el).toHaveClass('active'); }); }); - it('should run the selected build', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/.atom-build.targets.json'; + it('should run the selected build', () => { + waitsForPromise(() => { + const file = __dirname + '/fixture/.atom-build.targets.json'; return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') .then(() => specHelpers.refreshAwaitTargets()); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:select-active-target'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.select-list li.build-target'); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); }); }); - it('should run the default target if no selection has been made', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/.atom-build.targets.json'; + it('should run the default target if no selection has been made', () => { + waitsForPromise(() => { + const file = __dirname + '/fixture/.atom-build.targets.json'; return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') .then(() => specHelpers.refreshAwaitTargets()); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); }); }); - it('run the selected target if selection has changed, and subsequent build should run that target', function () { - waitsForPromise(function () { - var file = __dirname + '/fixture/.atom-build.targets.json'; + it('run the selected target if selection has changed, and subsequent build should run that target', () => { + waitsForPromise(() => { + const file = __dirname + '/fixture/.atom-build.targets.json'; return specHelpers.vouch(fs.copy, file, directory + '/.atom-build.json') .then(() => specHelpers.refreshAwaitTargets()); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:select-active-target'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.select-list li.build-target'); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:move-down'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.select-list li.selected').textContent === 'Custom: Some customized build'; }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement.querySelector('.select-list'), 'core:confirm'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/customized/); atom.commands.dispatch(workspaceElement.querySelector('.build'), 'build:stop'); }); - waitsFor(function () { + waitsFor(() => { return !workspaceElement.querySelector('.build'); }); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/customized/); }); }); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index ad701a85..005d1ae1 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -1,17 +1,16 @@ 'use babel'; -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); -describe('BuildView', function() { - - var directory = null; - var workspaceElement = null; +describe('BuildView', () => { + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); @@ -23,15 +22,15 @@ describe('BuildView', function() { jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - runs(function() { + runs(() => { workspaceElement = atom.views.getView(atom.workspace); jasmine.attachToDOM(workspaceElement); }); - waitsForPromise(function() { - return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then(function (dir) { + waitsForPromise(() => { + return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then( (dir) => { return specHelpers.vouch(fs.realpath, dir); - }).then(function (dir) { + }).then( (dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); return atom.packages.activatePackage('build'); @@ -39,12 +38,12 @@ describe('BuildView', function() { }); }); - afterEach(function () { + afterEach(() => { fs.removeSync(directory); }); - describe('when output from build command should be viewed', function() { - it('should color output according to ansi escape codes', function () { + describe('when output from build command should be viewed', () => { + it('should color output according to ansi escape codes', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'printf "\\033[31mHello\\e[0m World"' })); @@ -53,17 +52,17 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output > span').style.color.match(/\d+/g)).toEqual([ '187', '0', '0' ]); }); }); - it('should output data even if no line break exists', function () { + it('should output data even if no line break exists', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'printf "data without linebreak"' })); @@ -72,40 +71,40 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/data without linebreak/); }); }); - it('should only break the line when an actual newline character appears', function () { + it('should only break the line when an actual newline character appears', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'node -e \'process.stdout.write("same"); setTimeout(function () { process.stdout.write(" line\\n") }, 200);\'' + cmd: 'node -e \'process.stdout.write("same"); setTimeout(() => { process.stdout.write(" line\\n") }, 200);\'' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function () { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function () { - var el = workspaceElement.querySelector('.build .output'); + runs(() => { + const el = workspaceElement.querySelector('.build .output'); /* Now we expect one line for the 'Executing...' row, one for the actual output and an empty one at the end. */ - var lines = el.textContent.split('\n'); + const lines = el.textContent.split('\n'); expect(lines.length).toEqual(3); expect(lines[1]).toEqual('same line'); }); }); - it('should escape HTML chars so the output is not garbled or missing', function() { + it('should escape HTML chars so the output is not garbled or missing', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -116,20 +115,20 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/<script type="text\/javascript">alert\('XSS!'\)<\/script>/); }); }); }); - describe('when a build is triggered', function () { - it('should include a timer of the build', function () { + describe('when a build is triggered', () => { + it('should include a timer of the build', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -144,7 +143,7 @@ describe('BuildView', function() { // which is expected below. If this waits longer than 2000 ms, we're in trouble. waits(1200); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build-timer').textContent).toMatch(/1.\d/); // stop twice to abort the build @@ -154,8 +153,8 @@ describe('BuildView', function() { }); }); - describe('when links are added', function () { - it('should only add one link per text, even if multiple is requested', function () { + describe('when links are added', () => { + it('should only add one link per text, even if multiple is requested', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -167,23 +166,23 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { - var output = workspaceElement.querySelector('.build .output'); + runs(() => { + const output = workspaceElement.querySelector('.build .output'); expect(output.children.length).toEqual(6); - for (var i = 0; i < output.children.length; i++) { + for (let i = 0; i < output.children.length; i++) { expect(output.children[i].id).toEqual('error-match-0-0'); } }); }); }); - describe('when panel orientation is altered', function () { - it('should show the panel at the bottom spot', function () { + describe('when panel orientation is altered', () => { + it('should show the panel at the bottom spot', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.config.set('build.panelOrientation', 'Bottom'); @@ -195,19 +194,19 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { - var bottomPanels = atom.workspace.getBottomPanels(); + runs(() => { + const bottomPanels = atom.workspace.getBottomPanels(); expect(bottomPanels.length).toEqual(1); expect(bottomPanels[0].item.constructor.name).toEqual('BuildView'); }); }); - it('should show the panel at the bottom spot', function () { + it('should show the panel at the bottom spot', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.config.set('build.panelOrientation', 'Left'); @@ -219,19 +218,19 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { - var panels = atom.workspace.getLeftPanels(); + runs(() => { + const panels = atom.workspace.getLeftPanels(); expect(panels.length).toEqual(1); expect(panels[0].item.constructor.name).toEqual('BuildView'); }); }); - it('should show the panel at the bottom spot', function () { + it('should show the panel at the bottom spot', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.config.set('build.panelOrientation', 'Top'); @@ -243,19 +242,19 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { - var panels = atom.workspace.getTopPanels(); + runs(() => { + const panels = atom.workspace.getTopPanels(); expect(panels.length).toEqual(1); expect(panels[0].item.constructor.name).toEqual('BuildView'); }); }); - it('should show the panel at the bottom spot', function () { + it('should show the panel at the bottom spot', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); atom.config.set('build.panelOrientation', 'Right'); @@ -267,13 +266,13 @@ describe('BuildView', function() { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('error'); }); - runs(function() { - var panels = atom.workspace.getRightPanels(); + runs(() => { + const panels = atom.workspace.getRightPanels(); expect(panels.length).toEqual(1); expect(panels[0].item.constructor.name).toEqual('BuildView'); }); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index af96dc28..f9348670 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -1,17 +1,16 @@ 'use babel'; -var fs = require('fs-extra'); -var temp = require('temp'); -var specHelpers = require('atom-build-spec-helpers'); +const fs = require('fs-extra'); +const temp = require('temp'); +const specHelpers = require('atom-build-spec-helpers'); -describe('Visible', function() { - - var directory = null; - var workspaceElement = null; +describe('Visible', () => { + let directory = null; + let workspaceElement = null; temp.track(); - beforeEach(function() { + beforeEach(() => { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); @@ -23,52 +22,52 @@ describe('Visible', function() { jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); - runs(function() { + runs(() => { workspaceElement = atom.views.getView(atom.workspace); jasmine.attachToDOM(workspaceElement); }); - waitsForPromise(function() { - return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then(function (dir) { + waitsForPromise(() => { + return specHelpers.vouch(temp.mkdir, { prefix: 'atom-build-spec-' }).then( (dir) => { return specHelpers.vouch(fs.realpath, dir); - }).then(function (dir) { + }).then( (dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); }); }); }); - afterEach(function () { + afterEach(() => { fs.removeSync(directory); }); - describe('when package is activated with panel visibility set to Keep Visible', function() { - beforeEach(function () { + describe('when package is activated with panel visibility set to Keep Visible', () => { + beforeEach(() => { atom.config.set('build.panelVisibility', 'Keep Visible'); - waitsForPromise(function () { + waitsForPromise(() => { return atom.packages.activatePackage('build'); }); }); - it('should not show build window', function() { + it('should not show build window', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); - describe('when package is activated with panel visibility set to Toggle', function () { - beforeEach(function () { + describe('when package is activated with panel visibility set to Toggle', () => { + beforeEach(() => { atom.config.set('build.panelVisibility', 'Toggle'); - waitsForPromise(function () { + waitsForPromise(() => { return atom.packages.activatePackage('build'); }); }); - describe('when build panel is toggled and it is visible', function() { - beforeEach(function () { + describe('when build panel is toggled and it is visible', () => { + beforeEach(() => { atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); - it('should hide the build panel', function() { + it('should hide the build panel', () => { expect(workspaceElement.querySelector('.build')).toExist(); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); @@ -77,8 +76,8 @@ describe('Visible', function() { }); }); - describe('when panel visibility is set to Show on Error', function() { - it('should only show the build panel if a build fails', function () { + describe('when panel visibility is set to Show on Error', () => { + it('should only show the build panel if a build fails', () => { atom.config.set('build.panelVisibility', 'Show on Error'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -92,11 +91,11 @@ describe('Visible', function() { /* Give it some reasonable time to show itself if there is a bug */ waits(200); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); - runs(function () { + runs(() => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'echo "Very bad..." && exit 2' })); @@ -105,22 +104,22 @@ describe('Visible', function() { // .atom-build.json is updated asynchronously... give it some time waits(200); - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); }); }); }); - describe('when panel visibility is set to Hidden', function() { - it('should not show the build panel if build succeeeds', function () { + describe('when panel visibility is set to Hidden', () => { + it('should not show the build panel if build succeeeds', () => { atom.config.set('build.panelVisibility', 'Hidden'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -134,12 +133,12 @@ describe('Visible', function() { /* Give it some reasonable time to show itself if there is a bug */ waits(200); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); - it('should not show the build panel if build fails', function () { + it('should not show the build panel if build fails', () => { atom.config.set('build.panelVisibility', 'Hidden'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -153,12 +152,12 @@ describe('Visible', function() { /* Give it some reasonable time to show itself if there is a bug */ waits(200); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); }); }); - it('should show the build panel if it is toggled', function () { + it('should show the build panel if it is toggled', () => { atom.config.set('build.panelVisibility', 'Hidden'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ @@ -171,16 +170,16 @@ describe('Visible', function() { waits(200); // Let build finish. Since UI component is not visible yet, there's nothing to poll. - runs(function () { + runs(() => { atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); - waitsFor(function() { + waitsFor(() => { return workspaceElement.querySelector('.build .title') && workspaceElement.querySelector('.build .title').classList.contains('success'); }); - runs(function() { + runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); From 5330ff921a3371afbdacd53a204f5f7b7c02968e Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 18:14:03 +0100 Subject: [PATCH 234/495] No focused spec (great, travis catches these: https://travis-ci.org/noseglid/atom-build/builds/92455293) --- spec/build-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/build-spec.js b/spec/build-spec.js index d1313ef5..85a13a33 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -52,7 +52,7 @@ describe('Build', () => { }); describe('when building', () => { - fit('should show build failed if build fails', () => { + it('should show build failed if build fails', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ From 09265e80c3104b080bb5196050477b4387153a76 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 18:22:15 +0100 Subject: [PATCH 235/495] Do not use es6 arrow function in test --- spec/build-view-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 005d1ae1..a4dfb6dc 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -83,7 +83,7 @@ describe('BuildView', () => { it('should only break the line when an actual newline character appears', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'node -e \'process.stdout.write("same"); setTimeout(() => { process.stdout.write(" line\\n") }, 200);\'' + cmd: 'node -e \'process.stdout.write("same"); setTimeout(function() { process.stdout.write(" line\\n") }, 200);\'' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); From 22ce378392e413bb90941d67bae68f8675bee753 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 22:50:29 +0100 Subject: [PATCH 236/495] Import rather than require in specs --- spec/build-confirm-spec.js | 8 ++++---- spec/build-error-match-spec.js | 6 +++--- spec/build-keymap-spec.js | 6 +++--- spec/build-spec.js | 6 +++--- spec/build-targets-spec.js | 8 ++++---- spec/build-view-spec.js | 6 +++--- spec/build-visible-spec.js | 6 +++--- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index e4f55f8e..00a4e532 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -1,9 +1,9 @@ 'use babel'; -const _ = require('lodash'); -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import _ from 'lodash'; +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('Confirm', () => { let directory = null; diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index c16bcceb..68d2ae51 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,8 +1,8 @@ 'use babel'; -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('Error Match', () => { const errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index 061699f8..f7c22006 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -1,8 +1,8 @@ 'use babel'; -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('Keymap', () => { let directory = null; diff --git a/spec/build-spec.js b/spec/build-spec.js index 85a13a33..abb716ec 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,8 +1,8 @@ 'use babel'; -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('Build', () => { const goodAtomBuildfile = __dirname + '/fixture/.atom-build.json'; diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 11e0acf7..a6536ada 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -1,9 +1,9 @@ 'use babel'; -const _ = require('lodash'); -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import _ from 'lodash'; +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('Target', () => { let directory = null; diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index a4dfb6dc..7097c1a4 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -1,8 +1,8 @@ 'use babel'; -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('BuildView', () => { let directory = null; diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index f9348670..72865fe0 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -1,8 +1,8 @@ 'use babel'; -const fs = require('fs-extra'); -const temp = require('temp'); -const specHelpers = require('atom-build-spec-helpers'); +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; describe('Visible', () => { let directory = null; From 334edd41b40a30d775b03745dd032111afc58f9c Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 21 Nov 2015 22:50:46 +0100 Subject: [PATCH 237/495] Let `tools` be part of build rather than global --- lib/build.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/build.js b/lib/build.js index aa4031fc..224d6314 100644 --- a/lib/build.js +++ b/lib/build.js @@ -12,7 +12,6 @@ import BuildView from './build-view'; import GoogleAnalytics from './google-analytics'; import ErrorMatcher from './error-matcher'; import BuildError from './build-error'; -let tools = [ require('./atom-build') ]; module.exports = { config: { @@ -88,6 +87,7 @@ module.exports = { this.buildView = new BuildView(); + this.tools = [ require('./atom-build') ]; this.targets = {}; this.activeTarget = {}; this.targetsLoading = {}; @@ -143,7 +143,7 @@ module.exports = { }, deactivate: function () { - tools.forEach(tool => { + this.tools.forEach(tool => { if (tool.off) { _.forEach(tool.ctx, ctx => tool.off.apply(ctx, [ 'refresh' ])); } @@ -191,7 +191,7 @@ module.exports = { const pathPromise = refreshPaths.map((p) => { this.targetsLoading[p] = true; this.targets[p] = this.targets[p] || []; - const settingsPromise = tools.filter((tool) => { + const settingsPromise = this.tools.filter((tool) => { tool.ctx = tool.ctx || []; tool.ctx[p] = tool.ctx[p] || {}; return tool.isEligable.apply(tool.ctx[p], [ p ]); @@ -479,9 +479,9 @@ module.exports = { if (!(builders instanceof Array)) { builders = [ builders ]; } - tools = _.union(tools, builders); + this.tools = _.union(this.tools, builders); return new Disposable(() => { - tools = _.difference(tools, builders); + this.tools = _.difference(this.tools, builders); }); } }; From f6adb1ed2ccd682664856f7041dfadb03b4bcf48 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 22 Nov 2015 11:30:15 +0100 Subject: [PATCH 238/495] Prepare 0.49.1 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b8e6b47..a31e7f09 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.49.0", + "version": "0.49.1", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 6fae23398a898625e3bf9c0d9f0c1c12ad91365d Mon Sep 17 00:00:00 2001 From: Charlie Bouthoorn Date: Sun, 22 Nov 2015 14:34:26 +0100 Subject: [PATCH 239/495] Fixed dependency. `package.json` uses `xregexp` as package name, but you use `XRegExp` in your project. Fixed in this file. --- lib/error-matcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 86445c9d..6c831425 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; -import { XRegExp } from 'XRegExp'; +import { XRegExp } from 'xregexp'; import { EventEmitter } from 'events'; import GoogleAnalytics from './google-analytics'; From 9167d6eb41217570f7167d51de533fb4eb913714 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 22 Nov 2015 20:24:56 +0100 Subject: [PATCH 240/495] Prepare 0.49.2 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a31e7f09..93cd417d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.49.1", + "version": "0.49.2", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 1ae8971d034574571abfb7b5cb8620583f0bab34 Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Sun, 22 Nov 2015 16:01:37 -0700 Subject: [PATCH 241/495] Refine README Shields. Added APM Installs, APM Version, ApppVeyor Shield, Slack Badge. Adjusted Travis and Gitter Badge. --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 48a767ec..ba135cfd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # Atom Build package -[![Build Travis](https://travis-ci.org/noseglid/atom-build.svg?branch=master)](https://travis-ci.org/noseglid/atom-build) -[![Gitter chat](https://badges.gitter.im/noseglid/atom-build.svg)](https://gitter.im/noseglid/atom-build) +[![Plugin installs](https://img.shields.io/apm/dm/build.svg?style=flat-square)](https://atom.io/packages/build) +[![Package version](https://img.shields.io/apm/v/build.svg?style=flat-square)](https://atom.io/packages/build) + +[![Travis.ci Shield](https://img.shields.io/travis/noseglid/atom-build/master.svg?style=flat-square&label=travis%20ci)](https://travis-ci.org/noseglid/atom-build) +[![AppVeyor Shield](https://img.shields.io/appveyor/ci/noseglid/atom-build/master.svg?style=flat-square&label=appveyor +)](https://ci.appveyor.com/project/noseglid/atom-build) + +[![Gitter chat](https://img.shields.io/badge/gitter-noseglid%2Fatom--build-24CE66.svg?style=flat-square)](https://gitter.im/noseglid/atom-build) +[![Slack Badge](https://img.shields.io/badge/chat-atom.io%20slack-ff69b4.svg?style=flat-square)](http://atom-slack.herokuapp.com/) + Automatically build your project inside your new favorite editor, Atom. From 3c3b427d0e07e7db6fb194e1b355dab78a225f76 Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Sun, 22 Nov 2015 16:09:08 -0700 Subject: [PATCH 242/495] Clean up function definition in main Build Package Object. As well, changed the exporting of the object. --- lib/build.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/build.js b/lib/build.js index 224d6314..eb932d03 100644 --- a/lib/build.js +++ b/lib/build.js @@ -13,7 +13,7 @@ import GoogleAnalytics from './google-analytics'; import ErrorMatcher from './error-matcher'; import BuildError from './build-error'; -module.exports = { +export default { config: { panelVisibility: { title: 'Panel Visibility', @@ -79,7 +79,7 @@ module.exports = { } }, - activate: function () { + activate() { // Manually append /usr/local/bin as it may not be set on some systems, // and it's common to have node installed here. Keep it at end so it won't // accidentially override any other node installation @@ -142,7 +142,7 @@ module.exports = { }); }, - deactivate: function () { + deactivate() { this.tools.forEach(tool => { if (tool.off) { _.forEach(tool.ctx, ctx => tool.off.apply(ctx, [ 'refresh' ])); @@ -156,7 +156,7 @@ module.exports = { clearTimeout(this.finishedTimer); }, - activePath: function () { + activePath() { const textEditor = atom.workspace.getActiveTextEditor(); if (!textEditor || !textEditor.getPath()) { /* default to building the first one if no editor is active */ @@ -174,7 +174,7 @@ module.exports = { }); }, - cmdDefaults: function (cwd) { + cmdDefaults(cwd) { return { env: {}, args: [], @@ -185,7 +185,7 @@ module.exports = { }; }, - refreshTargets: function (refreshPaths) { + refreshTargets(refreshPaths) { refreshPaths = refreshPaths || atom.project.getPaths(); const pathPromise = refreshPaths.map((p) => { @@ -266,7 +266,7 @@ module.exports = { }); }, - selectActiveTarget: function () { + selectActiveTarget() { const p = this.activePath(); const targets = this.targets[p]; const targetsView = new TargetsView(); @@ -285,7 +285,7 @@ module.exports = { }).catch((err) => targetsView.setError(err.message)); }, - replace: function (value, targetEnv) { + replace(value, targetEnv) { const env = _.extend({}, process.env, targetEnv); value = value.replace(/\$(\w+)/g, function (match, name) { return name in env ? env[name] : match; @@ -317,7 +317,7 @@ module.exports = { return value; }, - startNewBuild: function (source, targetName) { + startNewBuild(source, targetName) { const p = this.activePath(); targetName = targetName || this.activeTarget[p]; @@ -407,7 +407,7 @@ module.exports = { }); }, - abort: function (cb) { + abort(cb) { this.child.removeAllListeners('close'); this.child.on('close', () => { this.child = null; @@ -423,7 +423,7 @@ module.exports = { this.child.killed = true; }, - build: function (source, event) { + build(source, event) { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), () => { @@ -432,7 +432,7 @@ module.exports = { }); }, - doSaveConfirm: function (modifiedTextEditors, continuecb, cancelcb) { + doSaveConfirm(modifiedTextEditors, continuecb, cancelcb) { const saveAndContinue = (save) => { modifiedTextEditors.forEach((textEditor) => save && textEditor.save()); continuecb(); @@ -450,13 +450,13 @@ module.exports = { this.saveConfirmView.show(saveAndContinue, cancelcb); }, - unsavedTextEditors: function () { + unsavedTextEditors() { return atom.workspace.getTextEditors().filter((textEditor) => { return textEditor.isModified() && ('untitled' !== textEditor.getTitle()); }); }, - stop: function () { + stop() { clearTimeout(this.finishedTimer); if (this.child) { if (this.child.killed) { @@ -475,7 +475,7 @@ module.exports = { } }, - consumeBuilder: function (builders) { + consumeBuilder(builders) { if (!(builders instanceof Array)) { builders = [ builders ]; } From b561591f5b3781e5c17c5a39954e788b605c7fbe Mon Sep 17 00:00:00 2001 From: Kepler Sticka-Jones Date: Sun, 22 Nov 2015 16:17:10 -0700 Subject: [PATCH 243/495] Use new export syntax for functions and name. --- lib/atom-build.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index 9fcdc346..b98dc647 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -5,7 +5,7 @@ import fs from 'fs'; import _ from 'lodash'; import CSON from 'cson-parser'; -module.exports.niceName = 'Custom file'; +export const niceName = 'Custom file'; function getConfig(file) { const realFile = fs.realpathSync(file); @@ -32,14 +32,14 @@ function createBuildConfig(build, name) { }; } -module.exports.isEligable = function (cwd) { +export function isEligable(cwd) { this.files = [ '.atom-build.json', '.atom-build.cson' ] .map(file => path.join(cwd, file)) .filter(fs.existsSync); return 0 < this.files.length; -}; +} -module.exports.settings = function () { +export function settings() { const config = []; this.files.map(getConfig).forEach(build => { config.push( @@ -49,18 +49,18 @@ module.exports.settings = function () { }); return config; -}; +} -module.exports.on = function (ev, cb) { +export function on(ev, cb) { this.fileWatchers = this.fileWatchers || []; if ('refresh' !== ev || !this.files) { return; } this.fileWatchers.push(...this.files.map(file => fs.watch(file, cb))); -}; +} -module.exports.off = function (ev) { +export function off(ev) { this.fileWatchers = this.fileWatchers || []; if ('refresh' !== ev) { return; @@ -68,4 +68,4 @@ module.exports.off = function (ev) { this.fileWatchers.forEach(watcher => watcher.close()); this.fileWatchers = []; -}; +} From 55fb49123dec51a697f5d09fdc7d611f7fbd93d3 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 23 Nov 2015 20:48:37 +0100 Subject: [PATCH 244/495] Use eslint-config-atom-build --- .eslintrc | 25 ++----------------------- package.json | 3 +-- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/.eslintrc b/.eslintrc index 0c371ad1..3e2f0333 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,28 +1,7 @@ { "parser": "babel-eslint", "rules": { - "comma-dangle": 0, - "default-case": 0, - "func-names": 0, - "indent": [ 2, 2, { "SwitchCase": 1 } ], - "new-cap": [ 2, { "capIsNewExceptions": [ "XRegExp" ] } ], - "no-param-reassign": 0, - "no-unused-expressions": [ 2, { "allowTernary": true, "allowShortCircuit": true } ], - "no-unused-vars": [ 2, { "args": "none" } ], - "space-before-function-paren": [ 2, { "anonymous": "always", "named": "never" } ], - "yoda": 0 + "new-cap": [ 2, { "capIsNewExceptions": [ "XRegExp" ] } ] }, - "env": { - "es6": true, - "node": true, - "browser": true, - "jasmine": true - }, - "globals": { - "atom": true, - "waitsForPromise": true, - "fit": false, - "fdescribe": false - }, - "extends": "airbnb" + "extends": "atom-build" } diff --git a/package.json b/package.json index 93cd417d..1a61fd2a 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,10 @@ "cson-parser": "^1.2.0" }, "devDependencies": { + "eslint-config-atom-build": "^1.0.0", "atom-build-spec-helpers": "^0.3.0", "babel-eslint": "^4.1.5", "eslint": "^1.10.1", - "eslint-config-airbnb": "^1.0.0", - "eslint-plugin-react": "^3.10.0", "fs-extra": "^0.23.0", "temp": "^0.8.1" }, From 86011517187a99804f126889ce9937448af3b5ec Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 26 Nov 2015 19:02:48 +0100 Subject: [PATCH 245/495] Move away from deprecated CSS selector Fixes #231 --- styles/build.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/styles/build.less b/styles/build.less index 708a37fe..0b4cc5c1 100644 --- a/styles/build.less +++ b/styles/build.less @@ -76,8 +76,8 @@ } } -.panel-left .build, -.panel-right .build { +atom-panel.left .build, +atom-panel.right .build { .btn-container { float: none !important; .new-row { From 80f9fbec6d78495ec92f52c30ea0efb3161ed856 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 26 Nov 2015 20:22:46 +0100 Subject: [PATCH 246/495] Initial commit for v2 of consumeBuilder v2 accepts an ES6 class, which will be instanced with `new` (therefore the context is implicit). This will also make it more clear for build providers that it may be instanced multiple times simultaneously. --- lib/atom-build.js | 71 +++++++++++++++++++++++++++-------------------- lib/build.js | 48 ++++++++++++++++++-------------- package.json | 6 ++-- 3 files changed, 72 insertions(+), 53 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index b98dc647..468f132e 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -4,8 +4,7 @@ import path from 'path'; import fs from 'fs'; import _ from 'lodash'; import CSON from 'cson-parser'; - -export const niceName = 'Custom file'; +import EventEmitter from 'events'; function getConfig(file) { const realFile = fs.realpathSync(file); @@ -32,40 +31,52 @@ function createBuildConfig(build, name) { }; } -export function isEligable(cwd) { - this.files = [ '.atom-build.json', '.atom-build.cson' ] - .map(file => path.join(cwd, file)) - .filter(fs.existsSync); - return 0 < this.files.length; -} +export default class CustomFile extends EventEmitter { + constructor(cwd) { + super(); + this.cwd = cwd; + } -export function settings() { - const config = []; - this.files.map(getConfig).forEach(build => { - config.push( - createBuildConfig(build, build.name || 'default'), - ..._.map(build.targets, (target, name) => createBuildConfig(target, name)) - ); - }); + getNiceName() { + return 'Custom file'; + } - return config; -} + isEligible() { + console.log('eligible?', this.cwd); + this.files = [ '.atom-build.json', '.atom-build.cson' ] + .map(file => path.join(this.cwd, file)) + .filter(fs.existsSync); + return 0 < this.files.length; + } + + settings() { + const config = []; + this.files.map(getConfig).forEach(build => { + config.push( + createBuildConfig(build, build.name || 'default'), + ..._.map(build.targets, (target, name) => createBuildConfig(target, name)) + ); + }); -export function on(ev, cb) { - this.fileWatchers = this.fileWatchers || []; - if ('refresh' !== ev || !this.files) { - return; + return config; } - this.fileWatchers.push(...this.files.map(file => fs.watch(file, cb))); -} + on(ev, cb) { + this.fileWatchers = this.fileWatchers || []; + if ('refresh' !== ev || !this.files) { + return; + } -export function off(ev) { - this.fileWatchers = this.fileWatchers || []; - if ('refresh' !== ev) { - return; + this.fileWatchers.push(...this.files.map(file => fs.watch(file, cb))); } - this.fileWatchers.forEach(watcher => watcher.close()); - this.fileWatchers = []; + off(ev) { + this.fileWatchers = this.fileWatchers || []; + if ('refresh' !== ev) { + return; + } + + this.fileWatchers.forEach(watcher => watcher.close()); + this.fileWatchers = []; + } } diff --git a/lib/build.js b/lib/build.js index eb932d03..4ca60717 100644 --- a/lib/build.js +++ b/lib/build.js @@ -5,6 +5,7 @@ import path from 'path'; import _ from 'lodash'; import { Disposable } from 'atom'; import kill from 'tree-kill'; +import Grim from 'grim'; import SaveConfirmView from './save-confirm-view'; import TargetsView from './targets-view'; @@ -12,6 +13,7 @@ import BuildView from './build-view'; import GoogleAnalytics from './google-analytics'; import ErrorMatcher from './error-matcher'; import BuildError from './build-error'; +import CustomFile from './atom-build'; export default { config: { @@ -87,7 +89,8 @@ export default { this.buildView = new BuildView(); - this.tools = [ require('./atom-build') ]; + this.tools = [ CustomFile ]; + this.instancedTools = {}; // Ordered by project path this.targets = {}; this.activeTarget = {}; this.targetsLoading = {}; @@ -191,21 +194,17 @@ export default { const pathPromise = refreshPaths.map((p) => { this.targetsLoading[p] = true; this.targets[p] = this.targets[p] || []; - const settingsPromise = this.tools.filter((tool) => { - tool.ctx = tool.ctx || []; - tool.ctx[p] = tool.ctx[p] || {}; - return tool.isEligable.apply(tool.ctx[p], [ p ]); - }).map((tool) => { - GoogleAnalytics.sendEvent('build', 'tool eligible', tool.niceName); - - if (tool.on) { - tool.off.apply(tool.ctx[p], [ 'refresh' ]); - tool.on.apply(tool.ctx[p], [ 'refresh', this.refreshTargets.bind(this, [ p ]) ]); - } - return Promise.resolve().then(() => { - return tool.settings.apply(tool.ctx[p], [ p ]); - }).catch((err) => { + this.instancedTools[p] = (this.instancedTools[p] || []).map(t => t.removeAllListeners('refresh')).filter(() => false); + const settingsPromise = this.tools.map((Tool) => { + const tool = new Tool(p); + this.instancedTools[p].push(tool); + return tool; + }).filter(tool => tool.isEligible()).map(tool => { + GoogleAnalytics.sendEvent('build', 'tool eligible', tool.getNiceName()); + + tool.on('refresh', this.refreshTargets.bind(this, [ p ])); + return Promise.resolve().then(() => tool.settings()).catch((err) => { if (err instanceof SyntaxError) { atom.notifications.addError('Invalid build file.', { detail: 'You have a syntax error in your build file: ' + err.message, @@ -475,13 +474,20 @@ export default { } }, + consumeBuilderLegacy(builders) { + Grim.deprecate('Use v2 of builder provider instead', { packageName: 'build' }); + // if (!(builders instanceof Array)) { + // builders = [ builders ]; + // } + // this.tools = _.union(this.tools, builders); + // return new Disposable(() => { + // this.tools = _.difference(this.tools, builders); + // }); + }, + consumeBuilder(builders) { - if (!(builders instanceof Array)) { - builders = [ builders ]; - } + builders = Array.isArray(builders) ? builders : [ builders ]; this.tools = _.union(this.tools, builders); - return new Disposable(() => { - this.tools = _.difference(this.tools, builders); - }); + return new Disposable(() => this.tools = _.difference(this.tools, builders)); } }; diff --git a/package.json b/package.json index 1a61fd2a..b645e588 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "node-uuid": "^1.4.3", "tree-kill": "^0.1.1", "xregexp": "^2.0.0", - "cson-parser": "^1.2.0" + "cson-parser": "^1.2.0", + "grim": "^2.0.0" }, "devDependencies": { "eslint-config-atom-build": "^1.0.0", @@ -29,7 +30,8 @@ "consumedServices": { "builder": { "versions": { - "^1.0.0": "consumeBuilder" + "^1.0.0": "consumeBuilderLegacy", + "^2.0.0": "consumeBuilder" } } }, From e313e13b9b91ee00add731e4cc834302bfee2a6d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 26 Nov 2015 21:07:02 +0100 Subject: [PATCH 247/495] Add legacy-provider Also Deprecate providers using the legacy API. --- lib/atom-build.js | 1 - lib/build.js | 63 +++++++++++++++++++++--------------------- lib/provider-legacy.js | 32 +++++++++++++++++++++ 3 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 lib/provider-legacy.js diff --git a/lib/atom-build.js b/lib/atom-build.js index 468f132e..f8da687e 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -42,7 +42,6 @@ export default class CustomFile extends EventEmitter { } isEligible() { - console.log('eligible?', this.cwd); this.files = [ '.atom-build.json', '.atom-build.cson' ] .map(file => path.join(this.cwd, file)) .filter(fs.existsSync); diff --git a/lib/build.js b/lib/build.js index 4ca60717..06343632 100644 --- a/lib/build.js +++ b/lib/build.js @@ -14,6 +14,7 @@ import GoogleAnalytics from './google-analytics'; import ErrorMatcher from './error-matcher'; import BuildError from './build-error'; import CustomFile from './atom-build'; +import providerLegacy from './provider-legacy'; export default { config: { @@ -143,6 +144,10 @@ export default { this.refreshTargets(addedPaths); projectPaths = atom.project.getPaths(); }); + + atom.packages.getLoadedPackages() + .filter(p => ((((p.metadata.providedServices || {}).builder || {}).versions || {})['1.0.0'])) + .forEach(p => Grim.deprecate('Use 2.0.0 of builder service API instead', { packageName: p.name })); }, deactivate() { @@ -195,29 +200,32 @@ export default { this.targetsLoading[p] = true; this.targets[p] = this.targets[p] || []; - this.instancedTools[p] = (this.instancedTools[p] || []).map(t => t.removeAllListeners('refresh')).filter(() => false); - const settingsPromise = this.tools.map((Tool) => { - const tool = new Tool(p); - this.instancedTools[p].push(tool); - return tool; - }).filter(tool => tool.isEligible()).map(tool => { - GoogleAnalytics.sendEvent('build', 'tool eligible', tool.getNiceName()); - - tool.on('refresh', this.refreshTargets.bind(this, [ p ])); - return Promise.resolve().then(() => tool.settings()).catch((err) => { - if (err instanceof SyntaxError) { - atom.notifications.addError('Invalid build file.', { - detail: 'You have a syntax error in your build file: ' + err.message, - dismissable: true - }); - } else { - atom.notifications.addError('Ooops. Something went wrong.', { - detail: err.message + (err.stack ? '\n' + err.stack : ''), - dismissable: true - }); - } + this.instancedTools[p] = (this.instancedTools[p] || []) + .map(t => t.removeAllListeners('refresh')) + .filter(() => false); // Just empty the array + + const settingsPromise = this.tools + .map(Tool => new Tool(p)) + .filter(tool => tool.isEligible()) + .map(tool => { + this.instancedTools[p].push(tool); + GoogleAnalytics.sendEvent('build', 'tool eligible', tool.getNiceName()); + + tool.on('refresh', this.refreshTargets.bind(this, [ p ])); + return Promise.resolve().then(() => tool.settings()).catch(err => { + if (err instanceof SyntaxError) { + atom.notifications.addError('Invalid build file.', { + detail: 'You have a syntax error in your build file: ' + err.message, + dismissable: true + }); + } else { + atom.notifications.addError('Ooops. Something went wrong.', { + detail: err.message + (err.stack ? '\n' + err.stack : ''), + dismissable: true + }); + } + }); }); - }); return Promise.all(settingsPromise).then((settings) => { settings = [].concat.apply([], settings).filter(Boolean).map(setting => @@ -474,15 +482,8 @@ export default { } }, - consumeBuilderLegacy(builders) { - Grim.deprecate('Use v2 of builder provider instead', { packageName: 'build' }); - // if (!(builders instanceof Array)) { - // builders = [ builders ]; - // } - // this.tools = _.union(this.tools, builders); - // return new Disposable(() => { - // this.tools = _.difference(this.tools, builders); - // }); + consumeBuilderLegacy(builder) { + return this.consumeBuilder(providerLegacy(builder)); }, consumeBuilder(builders) { diff --git a/lib/provider-legacy.js b/lib/provider-legacy.js new file mode 100644 index 00000000..827014b3 --- /dev/null +++ b/lib/provider-legacy.js @@ -0,0 +1,32 @@ +'use babel'; + +export default function (legacyObject) { + return class LegacyProvider { + constructor(path) { + this.path = path; + this.ctx = {}; + } + + getNiceName() { + return legacyObject.niceName; + } + + isEligible() { + return legacyObject.isEligable.apply(this.ctx, [ this.path ]); + } + + settings() { + return legacyObject.settings.apply(this.ctx, [ this.path ]); + } + + on(event, cb) { + if (!legacyObject.on) return null; + return legacyObject.on.apply(this.ctx, [ event, cb ]); + } + + removeAllListeners(event) { + if (!legacyObject.off) return null; + return legacyObject.off.apply(this.ctx, [ event ]); + } + }; +} From 80e7da9a2be3fa8dbe10aae88fe226e57c9fd265 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 29 Nov 2015 11:39:47 +0100 Subject: [PATCH 248/495] Custom build extends EventEmitter --- lib/atom-build.js | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index f8da687e..ad59f47d 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -35,6 +35,11 @@ export default class CustomFile extends EventEmitter { constructor(cwd) { super(); this.cwd = cwd; + this.fileWatchers = []; + } + + destructor() { + this.fileWatchers.forEach(fw => fw.close()); } getNiceName() { @@ -49,6 +54,9 @@ export default class CustomFile extends EventEmitter { } settings() { + this.fileWatchers.forEach(fw => fw.close()); + this.fileWatchers = this.files.map(file => fs.watch(file, () => this.emit('refresh'))); + const config = []; this.files.map(getConfig).forEach(build => { config.push( @@ -59,23 +67,4 @@ export default class CustomFile extends EventEmitter { return config; } - - on(ev, cb) { - this.fileWatchers = this.fileWatchers || []; - if ('refresh' !== ev || !this.files) { - return; - } - - this.fileWatchers.push(...this.files.map(file => fs.watch(file, cb))); - } - - off(ev) { - this.fileWatchers = this.fileWatchers || []; - if ('refresh' !== ev) { - return; - } - - this.fileWatchers.forEach(watcher => watcher.close()); - this.fileWatchers = []; - } } From 5df49392406867b9082a912bda7c6f2f1abab23d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 29 Nov 2015 11:42:20 +0100 Subject: [PATCH 249/495] Let some methods in build provider be optional --- lib/build.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/build.js b/lib/build.js index 06343632..c2b7177a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -151,11 +151,11 @@ export default { }, deactivate() { - this.tools.forEach(tool => { - if (tool.off) { - _.forEach(tool.ctx, ctx => tool.off.apply(ctx, [ 'refresh' ])); - } - }); + _.map(this.instancedTools, (tools, cwd) => tools.forEach(tool => { + tool.removeAllListeners('refresh'); + tool.destructor && tool.destructor(); + })); + if (this.child) { this.child.removeAllListeners(); kill(this.child.pid, 'SIGKILL'); @@ -201,7 +201,7 @@ export default { this.targets[p] = this.targets[p] || []; this.instancedTools[p] = (this.instancedTools[p] || []) - .map(t => t.removeAllListeners('refresh')) + .map(t => t.removeAllListeners && t.removeAllListeners('refresh')) .filter(() => false); // Just empty the array const settingsPromise = this.tools @@ -211,7 +211,7 @@ export default { this.instancedTools[p].push(tool); GoogleAnalytics.sendEvent('build', 'tool eligible', tool.getNiceName()); - tool.on('refresh', this.refreshTargets.bind(this, [ p ])); + tool.on && tool.on('refresh', this.refreshTargets.bind(this, [ p ])); return Promise.resolve().then(() => tool.settings()).catch(err => { if (err instanceof SyntaxError) { atom.notifications.addError('Invalid build file.', { From e4ab2f32e77d37c5575850f18a85008732c2c3f6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 29 Nov 2015 11:42:41 +0100 Subject: [PATCH 250/495] Added README on creating providers --- README.md | 55 ++++++-------------- build-tools.md | 40 --------------- create-provider.md | 122 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 80 deletions(-) delete mode 100644 build-tools.md create mode 100644 create-provider.md diff --git a/README.md b/README.md index ba135cfd..d0d0fc9a 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,17 @@ Automatically build your project inside your new favorite editor, Atom. ![work work](https://noseglid.github.io/atom-build.gif) +## Build providers +The best way to use this `build` packages is via a build provider. +Build providers are plugins to `build` which enables specific build tools (such as `GNU Make`, `gradle` or `gulp`). +All available build providers are available on the [AtomBuild homepage](https://atombuild.github.io). + +Build providers are available in Atoms package manager and installed as +any other package. + + -## Specifying a build command -You can check out [the plugins list](build-tools.md) for common build tools. Install them as -you would any other package! +### Specifying a custom build command If no build tool is enough to suit your needs, you can create a file named `.atom-build.json` in your project root, and specify exactly how your project is built: @@ -59,7 +66,7 @@ in you environment (e.g. by setting the `PATH` var appropriately on UNIX-like systems). -### Configuration options +#### Configuration options Option | Required | Description -------------|----------------|----------------------- @@ -73,7 +80,7 @@ Option | Required | Description `keymap` | *[optional]* | A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. `targets` | *[optional]* | Additional targets which can be used to build variations of your project. -### Replacements +#### Replacements The following parameters will be replaced in `cmd`, any entry in `args`, `cwd` and values of `env`. They should all be enclosed in curly brackets `{}` @@ -144,42 +151,10 @@ The package should integrate via the service API. This is typically done in `pac }, ``` -The `build`-package will then call `providingFunction` when activated and expects an -object in return: -```javascript -{ - niceName: 'string', - isEligable: function (path) {}, - settings: function (path) {}, - on: function (ev, callback) {}, //optional - off: function (ev), //optional -} -``` - -The `niceName` is esthetic only and should be a `string` which is a human readable -description of the build configuration is provided. - -`isEligable` should be a function which must return synchronously. It will get one -argument, `path`, which is the root folder of the currently active project in Atom. -It should return `true` or `false` indicating if it can build that folder into something -sensible. Typically look for the existence of a build file such as `gulpfile.js` or `Makefile`. - -`settings` can return a Promise or an object.. It is called when it is time to build the project. -It can provide anything which is allowed by the [custom build configuration](#custom-build-config). -This includes the command, `cmd`, to execute, any arguments, `args`, and so on. - -_[optional]_ `on` will be called with a string which is the name of an event the build tool provider can emit. The build -tool provider should call the `callback` when the specified event occurs. Events `build` may ask for include: - * `refresh` - call the callback if you want to force `build` to refresh all targets. - this is common after the build file has been altered. - -_[optional]_ `off` will be called when `build` is no longer interested in that event. It may be because -`build` is being deactivated, or refreshing its state. `build` will never call `off` for an event unless it has -previoused registered a listener via `on` first. +Creating a build provider require very little code in the easiest case, and can +be as complicated as necessary to achieve the correct functionality. -All functions will be called with the same value for `this` (which is an empty object at first). If you have to make -any time consuming computation in for instance `isEligable` it may be wise to store the result in `this` and -reuse it in `settings`. +Read more about building your own provider in [the create provider documentation](create-provider.md). ## Analytics diff --git a/build-tools.md b/build-tools.md deleted file mode 100644 index cbb39f2f..00000000 --- a/build-tools.md +++ /dev/null @@ -1,40 +0,0 @@ -# Community build tools for [atom-build](https://atom.io/packages/build) - -| Tool | Plugin | -|----------------|---------------------------| -| [GNU Make][1] | [build-make][2] | -| [gulp][3] | [build-gulp][4] | -| [grunt][5] | [build-grunt][6] | -| [npm][7] | [build-npm-apm][8] | -| [apm][9] | [build-npm-apm][8] | -| [Cargo][10] | [build-cargo][11] | -| [Elixir][12] | [build-elixir][13] | -| [Markdown][14] | [build-markdown][15] | -| [Gradle][16] | [build-gradle][17] | -| [JPM][18] | [build-jpm][19] | -| [sbt][20] | [build-sbt][21] | - -Have you created a build plugin and want it displayed here? -Create a pull request modifying this list. - -[1]: https://www.gnu.org/software/make/ -[2]: https://atom.io/packages/build-make -[3]: http://gulpjs.com/ -[4]: https://atom.io/packages/build-gulp -[5]: http://gruntjs.com/ -[6]: https://atom.io/packages/build-grunt -[7]: https://www.npmjs.com/ -[8]: https://atom.io/packages/build-npm-apm -[9]: https://github.com/atom/apm -[10]: https://crates.io/ -[11]: https://atom.io/packages/build-cargo -[12]: http://elixir-lang.org/ -[13]: https://atom.io/packages/build-elixir -[14]: http://daringfireball.net/projects/markdown/ -[15]: https://atom.io/packages/build-markdown -[16]: https://gradle.org/ -[17]: https://atom.io/packages/build-gradle -[18]: https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/jpm -[19]: https://atom.io/packages/build-jpm -[20]: https://scala-sbt.org -[21]: https://atom.io/packages/build-sbt diff --git a/create-provider.md b/create-provider.md new file mode 100644 index 00000000..cd488337 --- /dev/null +++ b/create-provider.md @@ -0,0 +1,122 @@ +# Creating a build provider + +The `build`-package will then call `providingFunction` when activated and expects an +ES6 class in return +```javascript +class MyBuildProvider { + + constructor(cwd) { + // OPTIONAL: setup here + // cwd is the project root this provider will operate in, so store `cwd` in `this`. + } + + destructor() { + // OPTIONAL: tear down here. + // destructor is not part of ES6. This is called by `build` like any + // other method before deactivating. + return 'void'; + } + + getNiceName() { + // REQUIRED: return a nice readable name of this provider. + return 'string'; + } + + isEligible() { + // REQUIRED: Perform operations to determine if this build provider can + // build the project in `cwd` (which was specified in `constructor`). + return 'boolean'; + } + + settings() { + // REQUIRED: Return an array of objects which each define a build description. + return 'array of objects'; // [ { ... }, { ... }, ] + } + + on(event, cb) { + // OPTIONAL: The build provider can let `build` know when it is time to + // refresh targets. + return 'void'; + } + + removeAllListeners(event) { + // OPTIONAL: (required if `on` is defined) removes all listeners registered in `on` + return 'void'; + } +} +``` + +--- + +`constructor` _[optional]_ - is used in ES6 classes to initialize the class. The path +where this instance of the build provider will operate is provided. +Please note that the build provider will be instanced once per project folder. + +--- + +`destructor` _[optional]_ - will be called before `build` is deactivated and gives you a chance +to release any resources claimed. + +--- + +The `getNiceName` - method is esthetic only and should be a `string` which is a human readable +description of the build configuration is provided. + +--- + +`isEligible` - should be a function which must return synchronously. +It should return `true` or `false` indicating if it can build the folder specified in the constructor into something +sensible. Typically look for the existence of a build file such as `gulpfile.js` or `Makefile`. + +--- + +`settings` - can return a Promise or an array of objects. +It can provide anything which is allowed by the [custom build configuration](README.md#custom-build-config). +This includes the command, `cmd`, to execute, any arguments, `args`, and so on. + +--- + +`on` _[optional]_ - will be called with a string which is the name of an event the build tool provider can emit. The build +tool provider should call the `callback` when the specified event occurs. +The easiest way to use this is to extends [NodeJS's event emitter](https://nodejs.org/api/events.html#events_class_events_eventemitter) and simply issue `this.emit(event)`. +Events `build` may ask for include: + * `refresh` - call the callback if you want `build` to refresh all targets. + this is common after the build file has been altered. +Note: If you extend `EventEmitter` you don't need to implement this method. + +--- + +`removeAllListeners` _[optional]_ - will be called when `build` is no longer interested in that event. It may be because +`build` is being deactivated, or refreshing its state. `build` will never call `removeAllListeners` for an event unless it has +previously registered a listener via `on` first. + +Note: If you extend `EventEmitter` you don't need to implement this method. + +--- + +## Operations + +Before `settings` is called, the build provider will always be given a chance to +let `build` know if it can do anything with the project folder by returning `true` or `false` +from the `isEligible` method. Checks for eligibility should always be performed here as +the content of the project folder may have changed between two calls. + +`build` will refresh targets for a variety of events: + * Atom is started, `build` will instance one build provider for every project root + folder in Atom and ask for build targets. + * A project root folder is added, `build` will instance a new build provider for this + folder and ask for build targets. + * Any build provider emits the `refresh`, in which case all providers in that folder + will be asked for targets. + * The user (or any other package) issues `build:refresh-targets` (e.g. via the command palette). + +## Publication + +If you want to share your provider (please do, if you needed it, chances are others will as well) +go to the [AtomBuild project for the homepage](https://github.com/AtomBuild/atombuild.github.io) +and follow the instructions there. Your tool will then be visisble on [https://atombuild.github.io](https://atombuild.github.io). This is also a great source to look +for existing build providers + +--- + +Happy coding! From 30324d1a0e57492587bac0e48e718af59357930c Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 29 Nov 2015 11:46:29 +0100 Subject: [PATCH 251/495] Documentation strucuturing For build provider api specifically --- README.md | 28 ++++------------------------ create-provider.md | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index d0d0fc9a..9599e84c 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ All available build providers are available on the [AtomBuild homepage](https:// Build providers are available in Atoms package manager and installed as any other package. +### Creating a build provider +Creating a build provider require very little code in the easiest case, and can +be as complicated as necessary to achieve the correct functionality. +Read more about building your own provider in [the create provider documentation](create-provider.md). ### Specifying a custom build command @@ -132,30 +136,6 @@ to cycle through the errors (in the order they appear, first on stderr then on s Often, the first error is the most interesting since other errors tend to be secondary faults caused by that first one. To jump to the first error you can use `cmd-alt-h` (OS X) or `shift-f4` (Linux/Windows) at any point to go to the first error. -## Service API (for package developers) - -Another package may provide build information to the `build`-package by implementing its service API. -The package should integrate via the service API. This is typically done in `package.json`: - -```javascript -{ - // - "providedServices": { - "builder": { - "description": "Description of the build configurations this package gives", - "versions": { - "1.0.0": "providingFunction" - } - } - } -}, -``` - -Creating a build provider require very little code in the easiest case, and can -be as complicated as necessary to achieve the correct functionality. - -Read more about building your own provider in [the create provider documentation](create-provider.md). - ## Analytics The `atom-build` package uses google analytics to keep track of which features are in use diff --git a/create-provider.md b/create-provider.md index cd488337..006ee647 100644 --- a/create-provider.md +++ b/create-provider.md @@ -1,7 +1,27 @@ # Creating a build provider +## Service API + +Another package may provide build information to the `build`-package by implementing its service API. +The package should integrate via the service API. This is typically done in `package.json`: + +```javascript +{ + "providedServices": { + "builder": { + "description": "Description of the build configurations this package gives", + "versions": { + "2.0.0": "providingFunction" + } + } + } +}, +``` + The `build`-package will then call `providingFunction` when activated and expects an -ES6 class in return +ES6 class in return. + +## The provider implementation. ```javascript class MyBuildProvider { From fe84d01d86acf3d54ae0a6d89e40afd464dfbe6b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 29 Nov 2015 11:49:58 +0100 Subject: [PATCH 252/495] More documentation cleanup --- create-provider.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/create-provider.md b/create-provider.md index 006ee647..b1f29b64 100644 --- a/create-provider.md +++ b/create-provider.md @@ -19,9 +19,10 @@ The package should integrate via the service API. This is typically done in `pac ``` The `build`-package will then call `providingFunction` when activated and expects an -ES6 class in return. +ES6 class in return. The next section describes in detail how that class is +expected to operate. -## The provider implementation. +## The provider implementation ```javascript class MyBuildProvider { @@ -66,8 +67,6 @@ class MyBuildProvider { } ``` ---- - `constructor` _[optional]_ - is used in ES6 classes to initialize the class. The path where this instance of the build provider will operate is provided. Please note that the build provider will be instanced once per project folder. @@ -79,14 +78,15 @@ to release any resources claimed. --- -The `getNiceName` - method is esthetic only and should be a `string` which is a human readable +`getNiceName` - aesthetic only and should be a `string` which is a human readable description of the build configuration is provided. --- `isEligible` - should be a function which must return synchronously. -It should return `true` or `false` indicating if it can build the folder specified in the constructor into something -sensible. Typically look for the existence of a build file such as `gulpfile.js` or `Makefile`. +It should return `true` or `false` indicating if it can build the folder specified +in the constructor into something sensible. Typically look for the existence of a +build file such as `gulpfile.js` or `Makefile`. --- @@ -102,6 +102,7 @@ The easiest way to use this is to extends [NodeJS's event emitter](https://nodej Events `build` may ask for include: * `refresh` - call the callback if you want `build` to refresh all targets. this is common after the build file has been altered. + Note: If you extend `EventEmitter` you don't need to implement this method. --- @@ -112,8 +113,6 @@ previously registered a listener via `on` first. Note: If you extend `EventEmitter` you don't need to implement this method. ---- - ## Operations Before `settings` is called, the build provider will always be given a chance to From d1986e95ead89a65b55b787fff4eeafcb71bfe48 Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Sun, 29 Nov 2015 18:04:39 -0800 Subject: [PATCH 253/495] add option to toggle if build should fail if error regex matches --- lib/build.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/build.js b/lib/build.js index eb932d03..e891ecb3 100644 --- a/lib/build.js +++ b/lib/build.js @@ -37,19 +37,26 @@ export default { default: false, order: 3 }, + matchedErrorFailsBuild: { + title: 'Any matched error will fail the build', + description: 'Even if the build has a return code of zero it is marked as "failed" if any error is being matched in the output.', + type: 'boolean', + default: true, + order: 4 + }, scrollOnError: { title: 'Automatically scroll on build error', description: 'Automatically scroll to first matched error when a build failed.', type: 'boolean', default: false, - order: 4 + order: 5 }, stealFocus: { title: 'Steal Focus', description: 'Steal focus when opening build panel.', type: 'boolean', default: true, - order: 5 + order: 6 }, monocleHeight: { title: 'Monocle Height', @@ -58,7 +65,7 @@ export default { default: 0.75, minimum: 0.1, maximum: 0.9, - order: 6 + order: 7 }, minimizedHeight: { title: 'Minimized Height', @@ -67,7 +74,7 @@ export default { default: 0.15, minimum: 0.1, maximum: 0.9, - order: 7 + order: 8 }, panelOrientation: { title: 'Panel Orientation', @@ -75,7 +82,7 @@ export default { type: 'string', default: 'Bottom', enum: [ 'Bottom', 'Top', 'Left', 'Right' ], - order: 8 + order: 9 } }, @@ -375,7 +382,10 @@ export default { this.child.on('close', (exitCode) => { this.errorMatcher.set(target.errorMatch, cwd, this.buildView.output.text()); - const success = (0 === exitCode) && !this.errorMatcher.hasMatch(); + let success = (0 === exitCode); + if (atom.config.get('build.matchedErrorFailsBuild')) { + success = success && !this.errorMatcher.hasMatch(); + } this.buildView.buildFinished(success); if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); From cde2ac33c5a85bb2fc799337952f30336d37b64f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 2 Dec 2015 08:44:14 +0100 Subject: [PATCH 254/495] README: Made AtomBuilds homepage stand out. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9599e84c..05898fae 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,10 @@ Automatically build your project inside your new favorite editor, Atom. ## Build providers The best way to use this `build` packages is via a build provider. Build providers are plugins to `build` which enables specific build tools (such as `GNU Make`, `gradle` or `gulp`). -All available build providers are available on the [AtomBuild homepage](https://atombuild.github.io). -Build providers are available in Atoms package manager and installed as +[AtomBuilds homepage](https://atombuild.github.io) for a list of build providers. + +Build providers can be downloaded via Atoms package manager and installed as any other package. ### Creating a build provider From 541b0dd76c78235251b1355ba551d12c087d5d17 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 2 Dec 2015 20:32:09 +0100 Subject: [PATCH 255/495] Prepare 0.50.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b645e588..fc496468 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.49.2", + "version": "0.50.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 71b2ae2071b680073f1792807013b163c1730fb8 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 3 Dec 2015 19:53:57 +0100 Subject: [PATCH 256/495] Only append /usr/local/bin on unix systems Fixes #216 --- lib/build.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/build.js b/lib/build.js index 58a4d423..35a270f5 100644 --- a/lib/build.js +++ b/lib/build.js @@ -90,10 +90,12 @@ export default { }, activate() { - // Manually append /usr/local/bin as it may not be set on some systems, - // and it's common to have node installed here. Keep it at end so it won't - // accidentially override any other node installation - process.env.PATH += ':/usr/local/bin'; + if (!/^win/.test(process.platform)) { + // Manually append /usr/local/bin as it may not be set on some systems, + // and it's common to have node installed here. Keep it at end so it won't + // accidentially override any other node installation + process.env.PATH += ':/usr/local/bin'; + } this.buildView = new BuildView(); From 9f2282c95b55da793799149f13d94700a4bf525f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 3 Dec 2015 20:08:39 +0100 Subject: [PATCH 257/495] When build failed, show the path Showing the path so it is easier to debug issues where command is not found. --- lib/build.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 58a4d423..02d7df55 100644 --- a/lib/build.js +++ b/lib/build.js @@ -382,7 +382,8 @@ export default { } if ('ENOENT' === err.code) { - this.buildView.append('Make sure `cmd` and `cwd` exists and have correct access permissions.'); + this.buildView.append('Make sure `cmd` and `cwd` exists and have correct access permissions.\n'); + this.buildView.append(`Build finds binaries in these folders: ${process.env.PATH}\n`); } }); From 973d60c9f8db31b885756a6d90bbc17e6c259419 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 3 Dec 2015 21:04:28 +0100 Subject: [PATCH 258/495] Update specificity of custom keymaps They will now reach the same specificity as the built in commands. Since they are applied later they will take precedence. Thus allowing custom keymaps to override built in keymaps. FIxes #239 --- lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 58a4d423..bce2584f 100644 --- a/lib/build.js +++ b/lib/build.js @@ -253,8 +253,8 @@ export default { GoogleAnalytics.sendEvent('keymap', 'registered', setting.keymap); const commandName = 'build:trigger:' + setting.name; - const keymapSpec = { 'atom-workspace': {} }; - keymapSpec['atom-workspace'][setting.keymap] = commandName; + const keymapSpec = { 'atom-workspace, atom-text-editor': {} }; + keymapSpec['atom-workspace, atom-text-editor'][setting.keymap] = commandName; const keymapDispose = atom.keymaps.add(setting.name, keymapSpec); const commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); settings[index].dispose = () => { From 3513779222f64208c417e44605f5c14104dbb119 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 25 Nov 2015 09:27:29 +0100 Subject: [PATCH 259/495] Newer CSON-parser Also added specs for CSON files --- lib/atom-build.js | 8 ++++++ package.json | 2 +- spec/custom-provider-spec.js | 47 +++++++++++++++++++++++++++++++++++ spec/fixture/.atom-build.cson | 6 +++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 spec/custom-provider-spec.js create mode 100644 spec/fixture/.atom-build.cson diff --git a/lib/atom-build.js b/lib/atom-build.js index ad59f47d..d027715d 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -68,3 +68,11 @@ export default class CustomFile extends EventEmitter { return config; } } + +export default { + niceName: this.niceName, + isEligable: this.isEligable, + settings: this.settings, + on: this.on, + off: this.off +}; diff --git a/package.json b/package.json index fc496468..b5756a09 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "node-uuid": "^1.4.3", "tree-kill": "^0.1.1", "xregexp": "^2.0.0", - "cson-parser": "^1.2.0", + "cson-parser": "^1.3.0", "grim": "^2.0.0" }, "devDependencies": { diff --git a/spec/custom-provider-spec.js b/spec/custom-provider-spec.js new file mode 100644 index 00000000..8c9c35f6 --- /dev/null +++ b/spec/custom-provider-spec.js @@ -0,0 +1,47 @@ +'use babel'; + +import fs from 'fs-extra'; +import temp from 'temp'; +import provider from '../lib/atom-build.js'; + +describe('Confirm', () => { + let directory = null; + + temp.track(); + + beforeEach(() => { + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + atom.project.setPaths([ directory ]); + }); + + afterEach(() => { + fs.removeSync(directory); + }); + + describe('when .atom-build.cson exists', () => { + it('it should be eligible targets', () => { + fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); + const ctx = {}; + const eligible = provider.isEligable.apply(ctx, [ directory ]); + + expect(eligible).toEqual(true); + }); + + it('it should provide targets', () => { + fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); + const ctx = {}; + const eligible = provider.isEligable.apply(ctx, [ directory ]); + expect(eligible).toEqual(true); + + Promise.resolve(provider.settings.apply(ctx, [ directory ])).then((settings) => { + const s = settings[0]; + expect(s.exec).toEqual('echo'); + expect(s.args).toEqual([ 'arg1', 'arg2' ]); + expect(s.name).toEqual('Custom: Compose masterpiece'); + expect(s.sh).toEqual(false); + expect(s.cwd).toEqual('/some/directory'); + expect(s.errorMatch).toEqual('(?\\w+.js):(?\\d+)'); + }); + }); + }); +}); diff --git a/spec/fixture/.atom-build.cson b/spec/fixture/.atom-build.cson new file mode 100644 index 00000000..447b6f86 --- /dev/null +++ b/spec/fixture/.atom-build.cson @@ -0,0 +1,6 @@ +cmd: "echo" +args: ["arg1", "arg2"] +cwd: "/some/directory" +sh: false +name: "Compose masterpiece" +errorMatch: "(?\\w+.js):(?\\d+)" From 4f64a0e898f857968fe2fa88d14e159d28f4077f Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 3 Dec 2015 21:40:17 +0100 Subject: [PATCH 260/495] Move specs to new build provider API --- lib/atom-build.js | 8 -------- spec/custom-provider-spec.js | 35 +++++++++++++++++------------------ 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index d027715d..ad59f47d 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -68,11 +68,3 @@ export default class CustomFile extends EventEmitter { return config; } } - -export default { - niceName: this.niceName, - isEligable: this.isEligable, - settings: this.settings, - on: this.on, - off: this.off -}; diff --git a/spec/custom-provider-spec.js b/spec/custom-provider-spec.js index 8c9c35f6..db96478d 100644 --- a/spec/custom-provider-spec.js +++ b/spec/custom-provider-spec.js @@ -2,9 +2,10 @@ import fs from 'fs-extra'; import temp from 'temp'; -import provider from '../lib/atom-build.js'; +import CustomFile from '../lib/atom-build.js'; -describe('Confirm', () => { +describe('custom provider', () => { + let builder; let directory = null; temp.track(); @@ -12,6 +13,7 @@ describe('Confirm', () => { beforeEach(() => { directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.setPaths([ directory ]); + builder = new CustomFile(directory); }); afterEach(() => { @@ -21,26 +23,23 @@ describe('Confirm', () => { describe('when .atom-build.cson exists', () => { it('it should be eligible targets', () => { fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); - const ctx = {}; - const eligible = provider.isEligable.apply(ctx, [ directory ]); - - expect(eligible).toEqual(true); + expect(builder.isEligible()).toEqual(true); }); it('it should provide targets', () => { fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); - const ctx = {}; - const eligible = provider.isEligable.apply(ctx, [ directory ]); - expect(eligible).toEqual(true); - - Promise.resolve(provider.settings.apply(ctx, [ directory ])).then((settings) => { - const s = settings[0]; - expect(s.exec).toEqual('echo'); - expect(s.args).toEqual([ 'arg1', 'arg2' ]); - expect(s.name).toEqual('Custom: Compose masterpiece'); - expect(s.sh).toEqual(false); - expect(s.cwd).toEqual('/some/directory'); - expect(s.errorMatch).toEqual('(?\\w+.js):(?\\d+)'); + expect(builder.isEligible()).toEqual(true); + + waitsForPromise(() => { + return Promise.resolve(builder.settings()).then(settings => { + const s = settings[0]; + expect(s.exec).toEqual('echo'); + expect(s.args).toEqual([ 'arg1', 'arg2' ]); + expect(s.name).toEqual('Custom: Compose masterpiece'); + expect(s.sh).toEqual(false); + expect(s.cwd).toEqual('/some/directory'); + expect(s.errorMatch).toEqual('(?\\w+.js):(?\\d+)'); + }); }); }); }); From a467b3d7777a6f9bf856c10b8c989e0f3666afcb Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 3 Dec 2015 21:45:18 +0100 Subject: [PATCH 261/495] Added specs form `.atom-build.json` --- spec/custom-provider-spec.js | 21 +++++++++++++++++++++ spec/fixture/.atom-build.json | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/spec/custom-provider-spec.js b/spec/custom-provider-spec.js index db96478d..da9d9086 100644 --- a/spec/custom-provider-spec.js +++ b/spec/custom-provider-spec.js @@ -43,4 +43,25 @@ describe('custom provider', () => { }); }); }); + + describe('when .atom-build.json exists', () => { + it('it should be eligible targets', () => { + fs.writeFileSync(`${directory}.atom-build.json`, fs.readFileSync(`${__dirname}/fixture/.atom-build.json`)); + expect(builder.isEligible()).toEqual(true); + }); + + it('it should provide targets', () => { + fs.writeFileSync(`${directory}.atom-build.json`, fs.readFileSync(`${__dirname}/fixture/.atom-build.json`)); + expect(builder.isEligible()).toEqual(true); + + waitsForPromise(() => { + return Promise.resolve(builder.settings()).then(settings => { + const s = settings[0]; + expect(s.exec).toEqual('dd'); + expect(s.args).toEqual([ 'if=.atom-build.json' ]); + expect(s.name).toEqual('Custom: Fly to moon'); + }); + }); + }); + }); }); diff --git a/spec/fixture/.atom-build.json b/spec/fixture/.atom-build.json index 2841ffb4..3f318a6c 100644 --- a/spec/fixture/.atom-build.json +++ b/spec/fixture/.atom-build.json @@ -1,4 +1,5 @@ { "cmd": "dd", - "args": [ "if=.atom-build.json" ] + "args": [ "if=.atom-build.json" ], + "name": "Fly to moon" } From e6a23b4a43ffd09859ce124734f44fb461cfa640 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 5 Dec 2015 12:09:23 +0100 Subject: [PATCH 262/495] README: .atom-build.cson --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 05898fae..8c4c868f 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ Read more about building your own provider in [the create provider documentation ### Specifying a custom build command If no build tool is enough to suit your needs, you can create a file named `.atom-build.json` +(it may also be `.atom-build.cson` if [CoffeeScript Object Notation](https://github.com/bevry/cson) is +your cup of tea). in your project root, and specify exactly how your project is built: { From 2a6f66eeea340c9201cfa3a90d4fea15cd575384 Mon Sep 17 00:00:00 2001 From: dreamair Date: Fri, 11 Dec 2015 18:00:12 +0100 Subject: [PATCH 263/495] (partly) cross-platform build specs via cmd (sh:true) for windows (partly) because arguments might still depend on the platform (windows path separators). Since this is less an issue with node processes, this enhancement can still be valuable. --- lib/build.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index f929f28e..8b5468db 100644 --- a/lib/build.js +++ b/lib/build.js @@ -357,10 +357,11 @@ export default { const exec = this.replace(target.exec, target.env); const args = target.args.map(arg => this.replace(arg, target.env)); const cwd = this.replace(target.cwd, target.env); + const isWin = process.platform == 'win32'; this.child = require('child_process').spawn( - target.sh ? '/bin/sh' : exec, - target.sh ? [ '-c', [ exec ].concat(args).join(' ') ] : args, + target.sh ? isWin ? 'cmd' : '/bin/sh' : exec, + target.sh ? [ isWin ? '/C' : '-c', [ path.normalize(exec) ].concat(args).join(' ') ] : args, { cwd: cwd, env: env } ); From 25cac5947ca071d1c01d35f6be634c40846aa8f9 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 13 Dec 2015 12:39:54 +0100 Subject: [PATCH 264/495] Status bar integration Shows the currently selected build target and the outcome of the last build on the status bar. This is extra handy if panel visibility is set to hidden. Includes options for putting it on the left or right side of the status bar, or disabling it all together. Fixes #253 --- lib/build.js | 48 ++++++++++++++++++++++++++--- lib/status-bar-view.js | 70 ++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +++ styles/build.less | 10 ++++++ 4 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 lib/status-bar-view.js diff --git a/lib/build.js b/lib/build.js index f929f28e..bb2f070c 100644 --- a/lib/build.js +++ b/lib/build.js @@ -8,6 +8,7 @@ import kill from 'tree-kill'; import Grim from 'grim'; import SaveConfirmView from './save-confirm-view'; +import StatusBarView from './status-bar-view'; import TargetsView from './targets-view'; import BuildView from './build-view'; import GoogleAnalytics from './google-analytics'; @@ -61,6 +62,13 @@ export default { default: true, order: 6 }, + selectTriggers: { + title: 'Selecting new target triggers the build', + description: 'When selecting a new target (through status-bar, cmd-alt-t, etc), the newly selected target will be triggered.', + type: 'boolean', + default: true, + order: 7 + }, monocleHeight: { title: 'Monocle Height', description: 'How much of the workspace to use for build panel when it is "maximized".', @@ -68,7 +76,7 @@ export default { default: 0.75, minimum: 0.1, maximum: 0.9, - order: 7 + order: 8 }, minimizedHeight: { title: 'Minimized Height', @@ -77,7 +85,7 @@ export default { default: 0.15, minimum: 0.1, maximum: 0.9, - order: 8 + order: 9 }, panelOrientation: { title: 'Panel Orientation', @@ -85,7 +93,15 @@ export default { type: 'string', default: 'Bottom', enum: [ 'Bottom', 'Top', 'Left', 'Right' ], - order: 9 + order: 10 + }, + statusBar: { + title: 'Status Bar', + description: 'Where to place the status bar. Set to `Disable` to disable status bar display.', + type: 'string', + default: 'Left', + enum: [ 'Left', 'Right', 'Disable' ], + order: 11 } }, @@ -132,6 +148,8 @@ export default { }); }); + atom.workspace.onDidChangeActivePaneItem(() => this.updateStatusBar()); + this.errorMatcher.on('error', (message) => { atom.notifications.addError('Error matching failed!', { detail: message }); }); @@ -170,6 +188,9 @@ export default { kill(this.child.pid, 'SIGKILL'); this.child = null; } + + this.statusBarView.destroy(); + clearTimeout(this.finishedTimer); }, @@ -191,6 +212,11 @@ export default { }); }, + updateStatusBar() { + const activeTarget = this.activeTarget[this.activePath()]; + this.statusBarView.setTarget(activeTarget); + }, + cmdDefaults(cwd) { return { env: {}, @@ -267,6 +293,7 @@ export default { this.targets[p] = settings; this.targetsLoading[p] = false; + this.updateStatusBar(); }); }); @@ -295,9 +322,12 @@ export default { targetsView.setItems((targets || []).map(target => target.name)); targetsView.awaitSelection().then((newTarget) => { this.activeTarget[p] = newTarget; + this.updateStatusBar(); - const workspaceElement = atom.views.getView(atom.workspace); - atom.commands.dispatch(workspaceElement, 'build:trigger'); + if (atom.config.get('build.selectTriggers')) { + const workspaceElement = atom.views.getView(atom.workspace); + atom.commands.dispatch(workspaceElement, 'build:trigger'); + } }).catch((err) => targetsView.setError(err.message)); }, @@ -397,6 +427,8 @@ export default { success = success && !this.errorMatcher.hasMatch(); } this.buildView.buildFinished(success); + this.statusBarView.setBuildSuccess(success); + if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); this.finishedTimer = setTimeout(() => { @@ -503,5 +535,11 @@ export default { builders = Array.isArray(builders) ? builders : [ builders ]; this.tools = _.union(this.tools, builders); return new Disposable(() => this.tools = _.difference(this.tools, builders)); + }, + + consumeStatusBar(statusBar) { + this.statusBarView = new StatusBarView(statusBar); + this.statusBarView.onClick(() => this.selectActiveTarget()); + this.statusBarView.attach(); } }; diff --git a/lib/status-bar-view.js b/lib/status-bar-view.js new file mode 100644 index 00000000..a01ba86c --- /dev/null +++ b/lib/status-bar-view.js @@ -0,0 +1,70 @@ +'use babel'; + +import { View } from 'atom-space-pen-views'; + +export default class StatusBarView extends View { + constructor(statusBar, ...args) { + super(...args); + this.statusBar = statusBar; + atom.config.observe('build.statusBar', () => this.attach()); + } + + attach() { + this.destroy(); + + const orientation = atom.config.get('build.statusBar'); + if ('Disable' === orientation) { + return; + } + + this.statusBarTile = this.statusBar[`add${orientation}Tile`]({ item: this, priority: -1000 }); + + this.tooltip = atom.tooltips.add(this, { + title: () => this.tooltipMessage() + }); + } + + destroy() { + if (this.statusBarTile) { + this.statusBarTile.destroy(); + this.statusBarTile = null; + } + + if (this.tooltip) { + this.tooltip.dispose(); + this.tooltip = null; + } + } + + static content() { + this.div({ id: 'build-status-bar', class: 'inline-block' }, () => { + this.span({ outlet: 'targetView' }); + this.a({ click: 'clicked', outlet: 'message'}); + }); + } + + tooltipMessage() { + const statusMessage = undefined === this.success ? '' : `Last build ${this.success ? 'succeeded' : 'failed'}!`; + return `Current build target is '${this.element.textContent}'
                  ${statusMessage}`; + } + + setTarget(t) { + this.target = t; + this.message.text(t); + this.targetView.removeClass('status-unknown status-success status-error icon-check icon-flame'); + } + + setBuildSuccess(success) { + this.success = success; + this.targetView.removeClass('status-unknown status-success status-error icon-check icon-flame'); + this.targetView.addClass(success ? 'status-success icon-check' : 'status-error icon-flame'); + } + + onClick(cb) { + this.onClick = cb; + } + + clicked() { + this.onClick && this.onClick(); + } +} diff --git a/package.json b/package.json index b5756a09..4c9d23fa 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,11 @@ "^1.0.0": "consumeBuilderLegacy", "^2.0.0": "consumeBuilder" } + }, + "status-bar": { + "versions": { + "^1.0.0": "consumeStatusBar" + } } }, "scripts": { diff --git a/styles/build.less b/styles/build.less index 0b4cc5c1..585a25a3 100644 --- a/styles/build.less +++ b/styles/build.less @@ -92,3 +92,13 @@ atom-panel.right .build { padding-right: @component-padding; } } + +#build-status-bar { + .status-success { + color: @text-color-success; + } + + .status-error { + color: @text-color-error; + } +} From fc953ef34e1bd2ceea5796a9bb5b04d95684dcd8 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 13 Dec 2015 12:48:55 +0100 Subject: [PATCH 265/495] Make sure statusBarView exists --- lib/build.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index bb2f070c..2283fc94 100644 --- a/lib/build.js +++ b/lib/build.js @@ -189,7 +189,7 @@ export default { this.child = null; } - this.statusBarView.destroy(); + this.statusBarView && this.statusBarView.destroy(); clearTimeout(this.finishedTimer); }, @@ -214,7 +214,7 @@ export default { updateStatusBar() { const activeTarget = this.activeTarget[this.activePath()]; - this.statusBarView.setTarget(activeTarget); + this.statusBarView && this.statusBarView.setTarget(activeTarget); }, cmdDefaults(cwd) { @@ -427,7 +427,7 @@ export default { success = success && !this.errorMatcher.hasMatch(); } this.buildView.buildFinished(success); - this.statusBarView.setBuildSuccess(success); + this.statusBarView && this.statusBarView.setBuildSuccess(success); if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); From 718f82c6b4348115bcd2e2da11f255648b36d81a Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 15 Dec 2015 15:56:20 +0100 Subject: [PATCH 266/495] Support for yaml custom file :cake: --- lib/atom-build.js | 6 +++++- lib/build.js | 23 +++++++++++++++++++++-- package.json | 7 ++++--- spec/custom-provider-spec.js | 21 +++++++++++++++++++++ spec/fixture/.atom-build.yml | 7 +++++++ 5 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 spec/fixture/.atom-build.yml diff --git a/lib/atom-build.js b/lib/atom-build.js index ad59f47d..e822d5eb 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -4,6 +4,7 @@ import path from 'path'; import fs from 'fs'; import _ from 'lodash'; import CSON from 'cson-parser'; +import yaml from 'js-yaml'; import EventEmitter from 'events'; function getConfig(file) { @@ -15,6 +16,9 @@ function getConfig(file) { case '.cson': return CSON.parse(fs.readFileSync(realFile)); + + case '.yml': + return yaml.safeLoad(fs.readFileSync(realFile)); } } @@ -47,7 +51,7 @@ export default class CustomFile extends EventEmitter { } isEligible() { - this.files = [ '.atom-build.json', '.atom-build.cson' ] + this.files = [ '.atom-build.json', '.atom-build.cson', '.atom-build.yml' ] .map(file => path.join(this.cwd, file)) .filter(fs.existsSync); return 0 < this.files.length; diff --git a/lib/build.js b/lib/build.js index f929f28e..60bb030f 100644 --- a/lib/build.js +++ b/lib/build.js @@ -202,6 +202,25 @@ export default { }; }, + settingsMakeUnique(settings) { + let diff; + const appender = (setting) => { + setting._uniqueIndex = setting._uniqueIndex || 1; + setting._originalName = setting._originalName || setting.name; + setting.name = `${setting._originalName} - ${setting._uniqueIndex++}`; + settings.push(setting); + }; + let i = 0; + do { + const uniqueSettings = _.uniq(settings, 'name'); + diff = _.difference(settings, uniqueSettings); + settings = uniqueSettings; + diff.forEach(appender); + } while (diff.length > 0 && i++ < 10); + + return settings; + }, + refreshTargets(refreshPaths) { refreshPaths = refreshPaths || atom.project.getPaths(); @@ -237,9 +256,9 @@ export default { }); return Promise.all(settingsPromise).then((settings) => { - settings = [].concat.apply([], settings).filter(Boolean).map(setting => + settings = this.settingsMakeUnique([].concat.apply([], settings).filter(Boolean).map(setting => _.defaults(setting, this.cmdDefaults(p)) - ); + )); if (_.isNull(this.activeTarget[p]) || !settings.find(s => s.name === this.activeTarget[p])) { /* Active target has been removed or not set. Set it to the highest prio target */ diff --git a/package.json b/package.json index b5756a09..01acb4f5 100644 --- a/package.json +++ b/package.json @@ -11,13 +11,14 @@ "dependencies": { "ansi_up": "^1.3.0", "atom-space-pen-views": "^2.0.3", + "cson-parser": "^1.3.0", "getmac": "^1.0.7", + "grim": "^2.0.0", + "js-yaml": "^3.4.6", "lodash": "^3.8.0", "node-uuid": "^1.4.3", "tree-kill": "^0.1.1", - "xregexp": "^2.0.0", - "cson-parser": "^1.3.0", - "grim": "^2.0.0" + "xregexp": "^2.0.0" }, "devDependencies": { "eslint-config-atom-build": "^1.0.0", diff --git a/spec/custom-provider-spec.js b/spec/custom-provider-spec.js index da9d9086..bea13cbb 100644 --- a/spec/custom-provider-spec.js +++ b/spec/custom-provider-spec.js @@ -64,4 +64,25 @@ describe('custom provider', () => { }); }); }); + + describe('when .atom-build.yml exists', () => { + it('it should be eligible targets', () => { + fs.writeFileSync(`${directory}.atom-build.yml`, fs.readFileSync(`${__dirname}/fixture/.atom-build.yml`)); + expect(builder.isEligible()).toEqual(true); + }); + + it('it should provide targets', () => { + fs.writeFileSync(`${directory}.atom-build.yml`, fs.readFileSync(`${__dirname}/fixture/.atom-build.yml`)); + expect(builder.isEligible()).toEqual(true); + + waitsForPromise(() => { + return Promise.resolve(builder.settings()).then(settings => { + const s = settings[0]; + expect(s.exec).toEqual('echo'); + expect(s.args).toEqual([ 'hello', 'world', 'from', 'yaml' ]); + expect(s.name).toEqual('Custom: yaml conf'); + }); + }); + }); + }); }); diff --git a/spec/fixture/.atom-build.yml b/spec/fixture/.atom-build.yml new file mode 100644 index 00000000..44b897f0 --- /dev/null +++ b/spec/fixture/.atom-build.yml @@ -0,0 +1,7 @@ +cmd: echo +args: + - hello + - world + - from + - yaml +name: yaml conf From a8aab287f5daea6d7554d3fb50b611b4918600b1 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 15 Dec 2015 16:05:37 +0100 Subject: [PATCH 267/495] Fix blinking keymap testcase If the build is slow, and/or build package closes the build panel due to its timeout, the toggle panel will really open the panel - causing the testcase to fail. Defer to always letting the panel be auto-closed and just wait for it to be closed. --- spec/build-keymap-spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index f7c22006..9749ca21 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -166,7 +166,6 @@ describe('Keymap', () => { runs(() => { expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); - atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); waitsFor(() => { From e0aef07a7ec4094b57338b99b0f24734f52c89d6 Mon Sep 17 00:00:00 2001 From: Charlie Bouthoorn Date: Tue, 15 Dec 2015 16:50:04 +0100 Subject: [PATCH 268/495] Update build.js Fixed linter errors --- lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 8b5468db..56c31945 100644 --- a/lib/build.js +++ b/lib/build.js @@ -357,10 +357,10 @@ export default { const exec = this.replace(target.exec, target.env); const args = target.args.map(arg => this.replace(arg, target.env)); const cwd = this.replace(target.cwd, target.env); - const isWin = process.platform == 'win32'; + const isWin = process.platform === 'win32'; this.child = require('child_process').spawn( - target.sh ? isWin ? 'cmd' : '/bin/sh' : exec, + target.sh ? ( isWin ? 'cmd' : '/bin/sh' ) : exec, target.sh ? [ isWin ? '/C' : '-c', [ path.normalize(exec) ].concat(args).join(' ') ] : args, { cwd: cwd, env: env } ); From 754caab814942bb2c1dcd6d02eed25f5e73703c7 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 15 Dec 2015 18:19:45 +0100 Subject: [PATCH 269/495] Prepare 0.51.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c357f6a..b696b1a4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.50.0", + "version": "0.51.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 24ff2a439fbafba55fc53821551013fb486cb396 Mon Sep 17 00:00:00 2001 From: AKFish Date: Sat, 19 Dec 2015 12:14:11 +0800 Subject: [PATCH 270/495] Initialize undefined environment variable properly --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 6f7420e2..5cea9d7e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -350,7 +350,7 @@ export default { }).catch((err) => targetsView.setError(err.message)); }, - replace(value, targetEnv) { + replace(value = '', targetEnv) { const env = _.extend({}, process.env, targetEnv); value = value.replace(/\$(\w+)/g, function (match, name) { return name in env ? env[name] : match; From b6544cf3454a472b461427e537aa33513ef0e7af Mon Sep 17 00:00:00 2001 From: Xpol Wan Date: Mon, 21 Dec 2015 21:42:30 +0800 Subject: [PATCH 271/495] Add status bar priority. --- lib/build.js | 7 +++++++ lib/status-bar-view.js | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 5cea9d7e..4bfe8b41 100644 --- a/lib/build.js +++ b/lib/build.js @@ -102,6 +102,13 @@ export default { default: 'Left', enum: [ 'Left', 'Right', 'Disable' ], order: 11 + }, + statusBarPriority: { + title: 'Priority on Status Bar', + description: 'Lower priority tiles are placed further to the left/right, depends on where you choose to place Status Bar.', + type: 'number', + default: -1000, + order: 12 } }, diff --git a/lib/status-bar-view.js b/lib/status-bar-view.js index a01ba86c..043772f0 100644 --- a/lib/status-bar-view.js +++ b/lib/status-bar-view.js @@ -7,6 +7,7 @@ export default class StatusBarView extends View { super(...args); this.statusBar = statusBar; atom.config.observe('build.statusBar', () => this.attach()); + atom.config.observe('build.statusBarPriority', () => this.attach()); } attach() { @@ -17,7 +18,7 @@ export default class StatusBarView extends View { return; } - this.statusBarTile = this.statusBar[`add${orientation}Tile`]({ item: this, priority: -1000 }); + this.statusBarTile = this.statusBar[`add${orientation}Tile`]({ item: this, priority: atom.config.get('build.statusBarPriority') }); this.tooltip = atom.tooltips.add(this, { title: () => this.tooltipMessage() From 197942c975b98e944266668bdeab23ce7673983c Mon Sep 17 00:00:00 2001 From: Selwyn Date: Mon, 21 Dec 2015 17:07:17 +0100 Subject: [PATCH 272/495] Fix typo by adding missing letter --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 5cea9d7e..6aad0d88 100644 --- a/lib/build.js +++ b/lib/build.js @@ -29,7 +29,7 @@ export default { }, buildOnSave: { title: 'Automatically build on save', - description: 'Autmatically build your project each time an editor is saved.', + description: 'Automatically build your project each time an editor is saved.', type: 'boolean', default: false, order: 2 From d832db279b49cbfb6975c01b61c321ddf7a71b48 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 22 Dec 2015 12:39:31 +0100 Subject: [PATCH 273/495] Do not throw an error if build config is missing Also updated test which tested for this condititon, however - the bug only occured after targets where refreshed, which they didn't have time for in the test. Fixes #269 --- lib/build.js | 2 +- spec/build-spec.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 9b1083a0..635c8e36 100644 --- a/lib/build.js +++ b/lib/build.js @@ -394,7 +394,7 @@ export default { targetName = targetName || this.activeTarget[p]; Promise.resolve(this.targets[p]).then(targets => { - if (!targets) { + if (!targets || 0 === targets.length) { throw new BuildError('No eligible build target.', 'No configuration to build this project exists.'); } diff --git a/spec/build-spec.js b/spec/build-spec.js index abb716ec..a335b309 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -434,6 +434,8 @@ describe('Build', () => { it('should not attempt to build if buildOnSave is true and no build tool exists', () => { atom.config.set('build.buildOnSave', true); + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + waitsForPromise(() => { return atom.workspace.open('dummy'); }); From ad4bec83a542db235deb7c96f4ef60d041e1b1ff Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 22 Dec 2015 12:54:07 +0100 Subject: [PATCH 274/495] Prepare 0.52.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b696b1a4..50b87e2f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.51.0", + "version": "0.52.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 90210d8fca678284493cc4ba2fd15d5f830d2170 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 12 Dec 2015 15:55:56 +0100 Subject: [PATCH 275/495] Added travis test matrix Now tests on linux and osx and in chanels stable and beta. --- .travis.yml | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index a665217e..ab2e006b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -language: objective-c - notifications: email: on_success: never @@ -12,11 +10,29 @@ notifications: on_failure: always on_start: false - -before_script: - - npm install - script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh' git: depth: 10 + +sudo: false + +os: + - linux + - osx + +env: + global: + - APM_TEST_PACKAGES="" + + matrix: + - ATOM_CHANNEL=stable + - ATOM_CHANNEL=beta + +addons: + apt: + packages: + - build-essential + - git + - libgnome-keyring-dev + - fakeroot From 4ef1f32f1565e6a0f3fe5422c6b191d8eafc7777 Mon Sep 17 00:00:00 2001 From: dreamair Date: Mon, 28 Dec 2015 15:39:04 +0100 Subject: [PATCH 276/495] try to work around lint errors --- lib/build.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 56c31945..14d36887 100644 --- a/lib/build.js +++ b/lib/build.js @@ -358,10 +358,12 @@ export default { const args = target.args.map(arg => this.replace(arg, target.env)); const cwd = this.replace(target.cwd, target.env); const isWin = process.platform === 'win32'; + const shCmd = isWin ? 'cmd' : '/bin/sh' + const shCmdArg = isWin ? '/C' : '-c' this.child = require('child_process').spawn( - target.sh ? ( isWin ? 'cmd' : '/bin/sh' ) : exec, - target.sh ? [ isWin ? '/C' : '-c', [ path.normalize(exec) ].concat(args).join(' ') ] : args, + target.sh ? shCmd : exec, + target.sh ? [ shCmdArg, [ path.normalize(exec) ].concat(args).join(' ') ] : args, { cwd: cwd, env: env } ); From 5006b957a142b74b2167c50adff60158e696497f Mon Sep 17 00:00:00 2001 From: dreamair Date: Mon, 28 Dec 2015 15:42:15 +0100 Subject: [PATCH 277/495] ...and the semicolons --- lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 14d36887..f11e9358 100644 --- a/lib/build.js +++ b/lib/build.js @@ -358,8 +358,8 @@ export default { const args = target.args.map(arg => this.replace(arg, target.env)); const cwd = this.replace(target.cwd, target.env); const isWin = process.platform === 'win32'; - const shCmd = isWin ? 'cmd' : '/bin/sh' - const shCmdArg = isWin ? '/C' : '-c' + const shCmd = isWin ? 'cmd' : '/bin/sh'; + const shCmdArg = isWin ? '/C' : '-c'; this.child = require('child_process').spawn( target.sh ? shCmd : exec, From e6e5263974a50387d5fd2843c0def36c7b09192c Mon Sep 17 00:00:00 2001 From: Xpol Wan Date: Mon, 11 Jan 2016 22:46:17 +0800 Subject: [PATCH 278/495] Changes editor font size will also affect build view. --- lib/build-view.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/build-view.js b/lib/build-view.js index 124287d9..8c6ba0b5 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -29,6 +29,7 @@ export default class BuildView extends View { atom.config.observe('build.monocleHeight', this.sizeFromConfig.bind(this)); atom.config.observe('build.minimizedHeight', this.sizeFromConfig.bind(this)); atom.config.observe('editor.fontFamily', this.fontFromConfig.bind(this)); + atom.config.observe('editor.fontSize', this.fontFromConfig.bind(this)); atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this)); } @@ -98,6 +99,7 @@ export default class BuildView extends View { fontFromConfig() { this.output.css('font-family', atom.config.get('editor.fontFamily')); + this.output.css('font-size', atom.config.get('editor.fontSize')); } visibleFromConfig(val) { From 909adb43f1705fdb877443849b247add62b8c67d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 19 Jan 2016 16:11:24 +0100 Subject: [PATCH 279/495] Option to hide notifications The refreshed targets notifications can be quite intrusive. Provide an option for disabling them. --- lib/build.js | 105 +++------------------------------ lib/config.js | 102 ++++++++++++++++++++++++++++++++ spec/build-confirm-spec.js | 1 + spec/build-error-match-spec.js | 1 + spec/build-keymap-spec.js | 1 + spec/build-spec.js | 1 + spec/build-targets-spec.js | 1 + spec/build-view-spec.js | 1 + spec/build-visible-spec.js | 1 + 9 files changed, 117 insertions(+), 97 deletions(-) create mode 100644 lib/config.js diff --git a/lib/build.js b/lib/build.js index ebe733dc..0cad9093 100644 --- a/lib/build.js +++ b/lib/build.js @@ -7,6 +7,7 @@ import { Disposable } from 'atom'; import kill from 'tree-kill'; import Grim from 'grim'; +import config from './config'; import SaveConfirmView from './save-confirm-view'; import StatusBarView from './status-bar-view'; import TargetsView from './targets-view'; @@ -18,99 +19,7 @@ import CustomFile from './atom-build'; import providerLegacy from './provider-legacy'; export default { - config: { - panelVisibility: { - title: 'Panel Visibility', - description: 'Set when the build panel should be visible.', - type: 'string', - default: 'Toggle', - enum: [ 'Toggle', 'Keep Visible', 'Show on Error', 'Hidden' ], - order: 1 - }, - buildOnSave: { - title: 'Automatically build on save', - description: 'Automatically build your project each time an editor is saved.', - type: 'boolean', - default: false, - order: 2 - }, - saveOnBuild: { - title: 'Automatically save on build', - description: 'Automatically save all edited files when triggering a build.', - type: 'boolean', - default: false, - order: 3 - }, - matchedErrorFailsBuild: { - title: 'Any matched error will fail the build', - description: 'Even if the build has a return code of zero it is marked as "failed" if any error is being matched in the output.', - type: 'boolean', - default: true, - order: 4 - }, - scrollOnError: { - title: 'Automatically scroll on build error', - description: 'Automatically scroll to first matched error when a build failed.', - type: 'boolean', - default: false, - order: 5 - }, - stealFocus: { - title: 'Steal Focus', - description: 'Steal focus when opening build panel.', - type: 'boolean', - default: true, - order: 6 - }, - selectTriggers: { - title: 'Selecting new target triggers the build', - description: 'When selecting a new target (through status-bar, cmd-alt-t, etc), the newly selected target will be triggered.', - type: 'boolean', - default: true, - order: 7 - }, - monocleHeight: { - title: 'Monocle Height', - description: 'How much of the workspace to use for build panel when it is "maximized".', - type: 'number', - default: 0.75, - minimum: 0.1, - maximum: 0.9, - order: 8 - }, - minimizedHeight: { - title: 'Minimized Height', - description: 'How much of the workspace to use for build panel when it is "minimized".', - type: 'number', - default: 0.15, - minimum: 0.1, - maximum: 0.9, - order: 9 - }, - panelOrientation: { - title: 'Panel Orientation', - description: 'Where to attach the build panel', - type: 'string', - default: 'Bottom', - enum: [ 'Bottom', 'Top', 'Left', 'Right' ], - order: 10 - }, - statusBar: { - title: 'Status Bar', - description: 'Where to place the status bar. Set to `Disable` to disable status bar display.', - type: 'string', - default: 'Left', - enum: [ 'Left', 'Right', 'Disable' ], - order: 11 - }, - statusBarPriority: { - title: 'Priority on Status Bar', - description: 'Lower priority tiles are placed further to the left/right, depends on where you choose to place Status Bar.', - type: 'number', - default: -1000, - order: 12 - } - }, + config: config, activate() { if (!/^win/.test(process.platform)) { @@ -328,10 +237,12 @@ export default { return; } - const rows = refreshPaths.map(p => `${this.targets[p].length} targets at: ${p}`); - atom.notifications.addInfo('Build targets parsed.', { - detail: rows.join('\n') - }); + if (atom.config.get('build.notificationOnRefresh')) { + const rows = refreshPaths.map(p => `${this.targets[p].length} targets at: ${p}`); + atom.notifications.addInfo('Build targets parsed.', { + detail: rows.join('\n') + }); + } }); }, diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 00000000..ee0beb8f --- /dev/null +++ b/lib/config.js @@ -0,0 +1,102 @@ +'use babel'; + +export default { + panelVisibility: { + title: 'Panel Visibility', + description: 'Set when the build panel should be visible.', + type: 'string', + default: 'Toggle', + enum: [ 'Toggle', 'Keep Visible', 'Show on Error', 'Hidden' ], + order: 1 + }, + buildOnSave: { + title: 'Automatically build on save', + description: 'Automatically build your project each time an editor is saved.', + type: 'boolean', + default: false, + order: 2 + }, + saveOnBuild: { + title: 'Automatically save on build', + description: 'Automatically save all edited files when triggering a build.', + type: 'boolean', + default: false, + order: 3 + }, + matchedErrorFailsBuild: { + title: 'Any matched error will fail the build', + description: 'Even if the build has a return code of zero it is marked as "failed" if any error is being matched in the output.', + type: 'boolean', + default: true, + order: 4 + }, + scrollOnError: { + title: 'Automatically scroll on build error', + description: 'Automatically scroll to first matched error when a build failed.', + type: 'boolean', + default: false, + order: 5 + }, + stealFocus: { + title: 'Steal Focus', + description: 'Steal focus when opening build panel.', + type: 'boolean', + default: true, + order: 6 + }, + selectTriggers: { + title: 'Selecting new target triggers the build', + description: 'When selecting a new target (through status-bar, cmd-alt-t, etc), the newly selected target will be triggered.', + type: 'boolean', + default: true, + order: 7 + }, + notificationOnRefresh: { + title: 'Show notification when targets are refreshed', + description: 'When targets are refreshed a notification with information about the number of targets will be displayed.', + type: 'boolean', + default: false, + order: 8 + }, + monocleHeight: { + title: 'Monocle Height', + description: 'How much of the workspace to use for build panel when it is "maximized".', + type: 'number', + default: 0.75, + minimum: 0.1, + maximum: 0.9, + order: 9 + }, + minimizedHeight: { + title: 'Minimized Height', + description: 'How much of the workspace to use for build panel when it is "minimized".', + type: 'number', + default: 0.15, + minimum: 0.1, + maximum: 0.9, + order: 10 + }, + panelOrientation: { + title: 'Panel Orientation', + description: 'Where to attach the build panel', + type: 'string', + default: 'Bottom', + enum: [ 'Bottom', 'Top', 'Left', 'Right' ], + order: 11 + }, + statusBar: { + title: 'Status Bar', + description: 'Where to place the status bar. Set to `Disable` to disable status bar display.', + type: 'string', + default: 'Left', + enum: [ 'Left', 'Right', 'Disable' ], + order: 12 + }, + statusBarPriority: { + title: 'Priority on Status Bar', + description: 'Lower priority tiles are placed further to the left/right, depends on where you choose to place Status Bar.', + type: 'number', + default: -1000, + order: 13 + } +}; diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 00a4e532..f39a59b0 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -18,6 +18,7 @@ describe('Confirm', () => { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); + atom.config.set('build.notificationOnRefresh', true); jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 68d2ae51..e9db36dd 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -26,6 +26,7 @@ describe('Error Match', () => { atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); atom.config.set('build.scrollOnError', false); + atom.config.set('build.notificationOnRefresh', true); atom.notifications.clear(); jasmine.unspy(window, 'setTimeout'); diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index 9749ca21..f9ba9950 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -17,6 +17,7 @@ describe('Keymap', () => { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); + atom.config.set('build.notificationOnRefresh', true); jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); diff --git a/spec/build-spec.js b/spec/build-spec.js index a335b309..10666124 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -23,6 +23,7 @@ describe('Build', () => { atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); atom.config.set('build.stealFocus', true); + atom.config.set('build.notificationOnRefresh', true); atom.notifications.clear(); workspaceElement = atom.views.getView(atom.workspace); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index a6536ada..a9a972c4 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -17,6 +17,7 @@ describe('Target', () => { atom.config.set('build.buildOnSave', false); atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); + atom.config.set('build.notificationOnRefresh', true); jasmine.unspy(window, 'setTimeout'); jasmine.unspy(window, 'clearTimeout'); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 7097c1a4..fb3d9597 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -15,6 +15,7 @@ describe('BuildView', () => { atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); atom.config.set('build.stealFocus', true); + atom.config.set('build.notificationOnRefresh', true); atom.notifications.clear(); workspaceElement = atom.views.getView(atom.workspace); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index 72865fe0..bbf6f289 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -15,6 +15,7 @@ describe('Visible', () => { atom.config.set('build.panelVisibility', 'Toggle'); atom.config.set('build.saveOnBuild', false); atom.config.set('build.stealFocus', true); + atom.config.set('build.notificationOnRefresh', true); atom.notifications.clear(); workspaceElement = atom.views.getView(atom.workspace); From ebb88e1aeb534d67268c8bfb50b696e490970813 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 19 Jan 2016 16:25:26 +0100 Subject: [PATCH 280/495] Prepare 0.53.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50b87e2f..fb158b8f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.52.0", + "version": "0.53.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 29508167301796a9340060bf824436126c65c7ef Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 19 Jan 2016 21:05:19 +0100 Subject: [PATCH 281/495] Keep build panel at end when error Fixes #278 --- lib/build-view.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 8c6ba0b5..6db020df 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -76,6 +76,7 @@ export default class BuildView extends View { this.panel = addfn[orientation].call(atom.workspace, { item: this }); this.sizeFromConfig(); this.fontFromConfig(); + this.output.scrollTop(this.output[0].scrollHeight); } detach(force) { @@ -215,7 +216,7 @@ export default class BuildView extends View { } buildFinished(success) { - if (!success) { + if (!success && !this.isAttached()) { this.attach(atom.config.get('build.panelVisibility') === 'Show on Error'); } this.titleText.text(success ? 'Build finished.' : 'Build failed.'); From a7f3d8a9a070991aec59ebcb3d6ecf9a0792352b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 19 Jan 2016 21:22:14 +0100 Subject: [PATCH 282/495] Spec: scroll bottom on build errored --- spec/build-view-spec.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index fb3d9597..68a836b8 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -279,4 +279,28 @@ describe('BuildView', () => { }); }); }); + + describe('when build fails', () => { + it('should keep the build scrolled to bottom', () => { + expect(workspaceElement.querySelector('.build')).not.toExist(); + + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: 'echo "a\nb\nc\nd\ne\nf\ng\nh\ni\nj" && exit 1' + })); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); + + waitsFor(() => { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(() => { + const el = workspaceElement.querySelector('.build .output'); + expect(el.scrollTop).toBeGreaterThan(0); + }); + }); + }); }); From 7d5b091f1440d3be16056cb1650cccbed7f6cb1b Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Wed, 20 Jan 2016 19:58:04 +0100 Subject: [PATCH 283/495] Fill an open target list once loaded If the targets list has been open, it is now required to re-open it once the targets-loading has finished. This fixes that so items are added to the existing list. --- lib/build.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/build.js b/lib/build.js index 0cad9093..e6edce78 100644 --- a/lib/build.js +++ b/lib/build.js @@ -228,6 +228,7 @@ export default { this.targets[p] = settings; this.targetsLoading[p] = false; + this.fillTargets(); this.updateStatusBar(); }); }); @@ -246,18 +247,24 @@ export default { }); }, + fillTargets() { + if (this.targetsView) { + const p = this.activePath(); + this.targetsView.setActiveTarget(this.activeTarget[p]); + this.targetsView.setItems((this.targets[p] || []).map(target => target.name)); + } + }, + selectActiveTarget() { const p = this.activePath(); - const targets = this.targets[p]; - const targetsView = new TargetsView(); + this.targetsView = new TargetsView(); if (this.targetsLoading[p]) { - return targetsView.setLoading('Loading project build targets\u2026'); + return this.targetsView.setLoading('Loading project build targets\u2026'); } - targetsView.setActiveTarget(this.activeTarget[p]); - targetsView.setItems((targets || []).map(target => target.name)); - targetsView.awaitSelection().then((newTarget) => { + this.fillTargets(); + this.targetsView.awaitSelection().then((newTarget) => { this.activeTarget[p] = newTarget; this.updateStatusBar(); @@ -265,7 +272,11 @@ export default { const workspaceElement = atom.views.getView(atom.workspace); atom.commands.dispatch(workspaceElement, 'build:trigger'); } - }).catch((err) => targetsView.setError(err.message)); + this.targetsView = null; + }).catch((err) => { + this.targetsView = null; + this.targetsView.setError(err.message); + }); }, replace(value = '', targetEnv) { From fb876e44c10a6a43cb388dd1ac9e7fe59b5f19f5 Mon Sep 17 00:00:00 2001 From: Rahlzel Date: Thu, 21 Jan 2016 03:50:10 -0500 Subject: [PATCH 284/495] New config option: "beepWhenDone". Makes a "beep" notification sound when the build is complete --- lib/build.js | 5 +++++ lib/config.js | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/build.js b/lib/build.js index e6edce78..2819144e 100644 --- a/lib/build.js +++ b/lib/build.js @@ -380,6 +380,10 @@ export default { this.buildView.buildFinished(success); this.statusBarView && this.statusBarView.setBuildSuccess(success); + if (atom.config.get('build.beepWhenDone')) { + atom.beep(); + } + if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); this.finishedTimer = setTimeout(() => { @@ -391,6 +395,7 @@ export default { } GoogleAnalytics.sendEvent('build', 'failed'); } + } this.child = null; }); diff --git a/lib/config.js b/lib/config.js index ee0beb8f..4a069943 100644 --- a/lib/config.js +++ b/lib/config.js @@ -58,6 +58,13 @@ export default { default: false, order: 8 }, + beepWhenDone: { + title: 'Beep when the build completes', + description: 'Make a "beep" notification sound when the build is complete - in success or failure.', + type: 'boolean', + default: false, + order: 9 + }, monocleHeight: { title: 'Monocle Height', description: 'How much of the workspace to use for build panel when it is "maximized".', @@ -65,7 +72,7 @@ export default { default: 0.75, minimum: 0.1, maximum: 0.9, - order: 9 + order: 10 }, minimizedHeight: { title: 'Minimized Height', @@ -74,7 +81,7 @@ export default { default: 0.15, minimum: 0.1, maximum: 0.9, - order: 10 + order: 11 }, panelOrientation: { title: 'Panel Orientation', @@ -82,7 +89,7 @@ export default { type: 'string', default: 'Bottom', enum: [ 'Bottom', 'Top', 'Left', 'Right' ], - order: 11 + order: 12 }, statusBar: { title: 'Status Bar', @@ -90,13 +97,13 @@ export default { type: 'string', default: 'Left', enum: [ 'Left', 'Right', 'Disable' ], - order: 12 + order: 13 }, statusBarPriority: { title: 'Priority on Status Bar', description: 'Lower priority tiles are placed further to the left/right, depends on where you choose to place Status Bar.', type: 'number', default: -1000, - order: 13 + order: 14 } }; From c76f2e481216535e2bc69475a0dc06ff4905fc5c Mon Sep 17 00:00:00 2001 From: Rahlzel Date: Thu, 21 Jan 2016 03:55:46 -0500 Subject: [PATCH 285/495] Oops. Removed a sneaky closing bracket. --- lib/build.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index 2819144e..9e850f6b 100644 --- a/lib/build.js +++ b/lib/build.js @@ -383,7 +383,7 @@ export default { if (atom.config.get('build.beepWhenDone')) { atom.beep(); } - + if (success) { GoogleAnalytics.sendEvent('build', 'succeeded'); this.finishedTimer = setTimeout(() => { @@ -395,7 +395,6 @@ export default { } GoogleAnalytics.sendEvent('build', 'failed'); } - } this.child = null; }); From 54436971de89a8972fe96ec0687e21cea01492d6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 21 Jan 2016 20:05:32 +0100 Subject: [PATCH 286/495] Layout: Less is more Modified the layout so that there is more space for the actual build output and altered feedback for errors, and building. --- lib/build-view.js | 54 ++++++++++----------- lib/build.js | 19 +++----- spec/build-spec.js | 3 +- styles/animations.less | 97 ++++++++++++++++++++++++++++++++++++ styles/build.less | 108 ++++++++++++++++++++++++----------------- 5 files changed, 195 insertions(+), 86 deletions(-) create mode 100644 styles/animations.less diff --git a/lib/build-view.js b/lib/build-view.js index 6db020df..049b52dd 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -8,15 +8,6 @@ import GoogleAnalytics from './google-analytics'; export default class BuildView extends View { constructor() { super(...arguments); - this.titleLoop = [ 'Building', 'Building.', 'Building..', 'Building...' ]; - this.titleLoop.rotate = function () { - /* Throttle as we don't want to update as quick as the timer is */ - this.n = this.n || 0; - if (++this.n === 3) { - this.push(this.shift()); - this.n = 0; - } - }; this.monocle = false; this.starttime = new Date(); this.buffer = new Buffer(0); @@ -34,23 +25,24 @@ export default class BuildView extends View { atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this)); } + static initialTimerText() { + return '0.0 s'; + } + static content() { this.div({ tabIndex: -1, class: 'build tool-panel panel-bottom native-key-bindings' }, () => { - this.div({ class: 'btn-container pull-right' }, () => { + this.div({ class: 'control-container pull-right opaque-hover' }, () => { this.button({ class: 'btn btn-default icon icon-x', click: 'close' }); this.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' }); this.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clear' }); this.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' }); + this.div({ class: 'title new-row', outlet: 'title' }, () => { + this.span({ class: 'icon icon-gear', outlet: 'gear' }); + this.span({ class: 'build-timer', outlet: 'buildTimer' }, this.initialTimerText()); + }); }); this.div({ class: 'output panel-body', outlet: 'output' }); - - this.div({ class: 'status' }, () => { - this.h1({ class: 'title panel-heading', outlet: 'title' }, ()=> { - this.span({ class: 'build-timer', outlet: 'buildTimer' }, '0.0 s'); - this.span({ class: 'title-text', outlet: 'titleText' }, 'Ready'); - }); - }); }); } @@ -125,18 +117,20 @@ export default class BuildView extends View { reset() { clearTimeout(this.titleTimer); + this.buildTimer.text(BuildView.initialTimerText()); this.buffer = new Buffer(0); this.links = []; this.titleTimer = 0; - this.title.removeClass('success error warning'); this.output.empty(); - this.titleText.text('Cleared.'); + + this.title.removeClass('success error'); + this.gear.removeClass('spin spin-flash'); + this.removeClass('success error'); + this.detach(); } updateTitle() { - this.titleText.text(this.titleLoop[0]); - this.titleLoop.rotate(); this.buildTimer.text(((new Date() - this.starttime) / 1000).toFixed(1) + ' s'); this.titleTimer = setTimeout(this.updateTitle.bind(this), 100); } @@ -212,6 +206,7 @@ export default class BuildView extends View { if (atom.config.get('build.stealFocus')) { this.focus(); } + this.gear.addClass('spin'); this.updateTitle(); } @@ -219,19 +214,22 @@ export default class BuildView extends View { if (!success && !this.isAttached()) { this.attach(atom.config.get('build.panelVisibility') === 'Show on Error'); } - this.titleText.text(success ? 'Build finished.' : 'Build failed.'); - this.title.addClass(success ? 'success' : 'error'); - clearTimeout(this.titleTimer); + this.finalizeBuild(success); } buildAbortInitiated() { - this.titleText.text('Build process termination imminent...'); - clearTimeout(this.titleTimer); - this.title.addClass('error'); + this.gear.removeClass('spin').addClass('spin-flash'); } buildAborted() { - this.titleText.text('Aborted!'); + this.finalizeBuild(false); + } + + finalizeBuild(success) { + this.title.addClass(success ? 'success' : 'error'); + this.addClass(success ? 'success' : 'error'); + this.gear.removeClass('spin spin-flash'); + clearTimeout(this.titleTimer); } _render() { diff --git a/lib/build.js b/lib/build.js index e6edce78..01dc8ba9 100644 --- a/lib/build.js +++ b/lib/build.js @@ -384,7 +384,7 @@ export default { GoogleAnalytics.sendEvent('build', 'succeeded'); this.finishedTimer = setTimeout(() => { this.buildView.detach(); - }, 1000); + }, 1200); } else { if (atom.config.get('build.scrollOnError')) { this.errorMatcher.matchFirst(); @@ -411,14 +411,16 @@ export default { }, abort(cb) { + this.child.removeAllListeners('exit'); this.child.removeAllListeners('close'); - this.child.on('close', () => { + this.child.on('exit', () => { + this.child.removeAllListeners(); this.child = null; cb && cb(); }); try { - kill(this.child.pid); + kill(this.child.pid, this.child.killed ? 'SIGKILL' : 'SIGTERM'); } catch (e) { /* Something may have happened to the child (e.g. terminated by itself). Ignore this. */ } @@ -462,17 +464,10 @@ export default { stop() { clearTimeout(this.finishedTimer); if (this.child) { - if (this.child.killed) { - // This child has been killed, but hasn't terminated. Hide it from user. - this.child.removeAllListeners(); - this.child = null; - this.buildView.buildAborted(); - return; + if (!this.child.killed) { + this.buildView.buildAbortInitiated(); } - this.abort(() => this.buildView.buildAborted()); - - this.buildView.buildAbortInitiated(); } else { this.buildView.reset(); } diff --git a/spec/build-spec.js b/spec/build-spec.js index 10666124..1b0ee8bc 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -110,6 +110,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Building, this will take some time.../); + expect(workspaceElement.querySelector('.build .title .icon-gear').classList.contains('spin')).toBe(true); atom.commands.dispatch(workspaceElement, 'build:stop'); }); @@ -123,7 +124,7 @@ describe('Build', () => { }); waitsFor(() => { - return (workspaceElement.querySelector('.build .title .title-text').textContent === 'Aborted!'); + return (!workspaceElement.querySelector('.build .title .icon-gear')); }); }); diff --git a/styles/animations.less b/styles/animations.less new file mode 100644 index 00000000..0b54005c --- /dev/null +++ b/styles/animations.less @@ -0,0 +1,97 @@ +@-webkit-keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.spin { + animation: spin 2.5s linear infinite; +} + +@-webkit-keyframes flash { + 0% { + opacity: 0.2; + } + 50% { + opacity: 1.0; + } + 100% { + opacity: 0.2; + } +} + +@-webkit-keyframes flash-background-success { + 0% { + background-color: rgba( + red(@background-color-success), + green(@background-color-success), + blue(@background-color-success), + 0 + ); + } + 20% { + background-color: rgba( + red(@background-color-success), + green(@background-color-success), + blue(@background-color-success), + 0.3 + ); + } + 80% { + background-color: rgba( + red(@background-color-success), + green(@background-color-success), + blue(@background-color-success), + 0.3 + ); + } + 100% { + background-color: rgba( + red(@background-color-success), + green(@background-color-success), + blue(@background-color-success), + 0 + ); + } +} + +@-webkit-keyframes flash-background-error { + 0% { + background-color: rgba( + red(@background-color-error), + green(@background-color-error), + blue(@background-color-error), + 0 + ); + } + 20% { + background-color: rgba( + red(@background-color-error), + green(@background-color-error), + blue(@background-color-error), + 0.3 + ); + } + 80% { + background-color: rgba( + red(@background-color-error), + green(@background-color-error), + blue(@background-color-error), + 0.3 + ); + } + 100% { + background-color: rgba( + red(@background-color-error), + green(@background-color-error), + blue(@background-color-error), + 0 + ); + } +} +.spin-flash { + animation: flash 0.5s linear infinite, spin 2.5s linear infinite; +} diff --git a/styles/build.less b/styles/build.less index 585a25a3..69d711d9 100644 --- a/styles/build.less +++ b/styles/build.less @@ -1,58 +1,33 @@ @import "ui-variables"; -@status-panel-height: 3em; +@import "animations"; + +@top-bot-control-width: 100px; .build { - height: 100%; + border-left: solid 1px @base-border-color; + border-bottom: solid 1px @base-border-color; font-family: 'Menlo', 'Consolas', 'DejaVu Sans Mono', monospace; + transition: background-color 0.2s ease-in; - .title { - transition: background-color 0.2s ease-in; + &.success { + animation: flash-background-success linear 1.2s; } - .build-timer { - display: inline-block; - width: 5em; - margin-right: @component-padding; - } - - .title.error { - color: white; - background-image: none; - background-color: @background-color-error; - } - - .title.success { - color: white; - background-image: none; - background-color: @background-color-success; - } - - .title.warning { - color: white; - background-image:none; - background-color: @background-color-warning; + &.error { + animation: flash-background-error linear 1.2s; } .output { transition: 0.5s ease-in-out; transition-property: width, height; - padding: @component-padding 0 @status-panel-height @component-padding; - min-height: 100px; + padding: (@component-padding / 2); + margin-right: @top-bot-control-width; + min-height: 125px; overflow: auto; word-wrap: break-word; white-space: pre-wrap; - } - - .status { - position: absolute; - bottom: 0; - height: @status-panel-height; - width: 100%; - h1 { - height: 100%; - } } a { @@ -60,13 +35,54 @@ } } -.btn-container { +.opaque-hover { + transition: opacity 0.2s linear; + opacity: 0.6; + &:hover { + opacity: 1.0; + } +} + +.control-container { + height: 100%; + -webkit-user-select: none; + position: absolute; + right: 0; + top: 0; + width: @top-bot-control-width; .btn { + width: 32px; float: right; margin: @component-padding @component-padding 0 0; color: @text-color-info; } + .title { + adding: 5px; + float: right; + font-size: 11px; + margin: @component-padding; + line-height: @component-line-height; + border-radius: 5px; + } + + .title.error { + color: @background-color-error; + } + + .title.success { + color: @background-color-success; + } + + .build-timer { + float: right; + margin-right: @component-padding; + } + + .icon-gear { + float: right; + } + .icon::before { margin: 0; } @@ -78,18 +94,20 @@ atom-panel.left .build, atom-panel.right .build { - .btn-container { + height: 100%; + .control-container { float: none !important; + position: relative; + display: block; + height: 40px; + width: 100%; .new-row { clear: none; } - .btn:last-child { - margin-left: @component-padding; - } } .output { - min-width: 200px; - padding-right: @component-padding; + margin-right: 0; + min-width: 250px; } } From f73ffd397339c4f5fa861f4053a86957eb456638 Mon Sep 17 00:00:00 2001 From: Dmytro Kyrychuk Date: Sat, 23 Jan 2016 13:16:56 +0200 Subject: [PATCH 287/495] Check if tool.removeAllListeners esists before call Some tools may not have `removeAllListeners` method, espetially those which do not extend `EventEmitter`. --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 43c3d747..1b933a91 100644 --- a/lib/build.js +++ b/lib/build.js @@ -95,7 +95,7 @@ export default { deactivate() { _.map(this.instancedTools, (tools, cwd) => tools.forEach(tool => { - tool.removeAllListeners('refresh'); + tool.removeAllListeners && tool.removeAllListeners('refresh'); tool.destructor && tool.destructor(); })); From 7a78f1c6c121c1e568de34ff81ebe72df0a398c0 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 25 Jan 2016 19:16:18 +0100 Subject: [PATCH 288/495] Add spinning gear to status bar When building, a spinning gear will appear in the status bar, so it is apparant that a build is in progress even if the build window is closed. --- lib/build.js | 1 + lib/status-bar-view.js | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/build.js b/lib/build.js index 1b933a91..ba853443 100644 --- a/lib/build.js +++ b/lib/build.js @@ -398,6 +398,7 @@ export default { this.child = null; }); + this.statusBarView.buildStarted(); this.buildView.buildStarted(); this.buildView.append([ (target.sh ? 'Executing with sh:' : 'Executing:'), exec, ...args, '\n'].join(' ')); }).catch((err) => { diff --git a/lib/status-bar-view.js b/lib/status-bar-view.js index 043772f0..7b75d697 100644 --- a/lib/status-bar-view.js +++ b/lib/status-bar-view.js @@ -18,7 +18,10 @@ export default class StatusBarView extends View { return; } - this.statusBarTile = this.statusBar[`add${orientation}Tile`]({ item: this, priority: atom.config.get('build.statusBarPriority') }); + this.statusBarTile = this.statusBar[`add${orientation}Tile`]({ + item: this, + priority: atom.config.get('build.statusBarPriority') + }); this.tooltip = atom.tooltips.add(this, { title: () => this.tooltipMessage() @@ -49,16 +52,24 @@ export default class StatusBarView extends View { return `Current build target is '${this.element.textContent}'
                  ${statusMessage}`; } + setClasses(classes) { + this.targetView.removeClass('status-unknown status-success status-error spin icon-gear icon-check icon-flame'); + this.targetView.addClass(classes); + } + setTarget(t) { this.target = t; this.message.text(t); - this.targetView.removeClass('status-unknown status-success status-error icon-check icon-flame'); + this.setClasses(); } setBuildSuccess(success) { this.success = success; - this.targetView.removeClass('status-unknown status-success status-error icon-check icon-flame'); - this.targetView.addClass(success ? 'status-success icon-check' : 'status-error icon-flame'); + this.setClasses(success ? 'status-success icon-check' : 'status-error icon-flame'); + } + + buildStarted() { + this.setClasses('icon-gear spin'); } onClick(cb) { From e6cae9ab386bd08524b0e6fd06a12f789ac3d4de Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 25 Jan 2016 20:23:54 +0100 Subject: [PATCH 289/495] Only call statusBarView if it exists. --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index ba853443..b55035e1 100644 --- a/lib/build.js +++ b/lib/build.js @@ -398,7 +398,7 @@ export default { this.child = null; }); - this.statusBarView.buildStarted(); + this.statusBarView && this.statusBarView.buildStarted(); this.buildView.buildStarted(); this.buildView.append([ (target.sh ? 'Executing with sh:' : 'Executing:'), exec, ...args, '\n'].join(' ')); }).catch((err) => { From b4c59f3080a6784a8e68f20e49e6662209ed86e4 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 26 Jan 2016 09:51:01 +0100 Subject: [PATCH 290/495] Only scroll output if at the end This way content can be searched while output is being appended. --- lib/build-view.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/build-view.js b/lib/build-view.js index 049b52dd..9342c92a 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -245,9 +245,12 @@ export default class BuildView extends View { } append(data) { + const shouldScroll = (this.output[0].scrollHeight - this.output[0].scrollTop === this.output[0].offsetHeight); this.buffer = Buffer.concat([ this.buffer, Buffer.isBuffer(data) ? data : new Buffer(data) ]); this._render(); - this.output.scrollTop(this.output[0].scrollHeight); + if (shouldScroll) { + this.output.scrollTop(this.output[0].scrollHeight); + } } link(text, id, onClick) { From 7d90f1c1493194aaca9424277094853277fd9123 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Tue, 26 Jan 2016 10:06:20 +0100 Subject: [PATCH 291/495] When build is aborted, update status-bar-view This stops the spinning gear, and sets the fire icon. --- lib/build.js | 5 ++++- lib/status-bar-view.js | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index b55035e1..cfa0da45 100644 --- a/lib/build.js +++ b/lib/build.js @@ -472,7 +472,10 @@ export default { if (!this.child.killed) { this.buildView.buildAbortInitiated(); } - this.abort(() => this.buildView.buildAborted()); + this.abort(() => { + this.buildView.buildAborted(); + this.statusBarView && this.statusBarView.buildAborted(); + }); } else { this.buildView.reset(); } diff --git a/lib/status-bar-view.js b/lib/status-bar-view.js index 7b75d697..9d5877a0 100644 --- a/lib/status-bar-view.js +++ b/lib/status-bar-view.js @@ -63,6 +63,10 @@ export default class StatusBarView extends View { this.setClasses(); } + buildAborted() { + this.setBuildSuccess(false); + } + setBuildSuccess(success) { this.success = success; this.setClasses(success ? 'status-success icon-check' : 'status-error icon-flame'); From 8facd8fee0b052d3220b2d0b8371c98c88ff11f1 Mon Sep 17 00:00:00 2001 From: Charlie Bouthoorn Date: Wed, 27 Jan 2016 16:13:46 +0100 Subject: [PATCH 292/495] Fixed typo "Let's you" means "Let us you", while "lets you" means "permits you" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c4c868f..740fd05e 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ values of `env`. They should all be enclosed in curly brackets `{}` ## Error matching -Error matching let's you specify a single regular expression or a list of +Error matching lets you specify a single regular expression or a list of regular expressions, which capture the output of your build command and open the correct file, row and column of the error. For instance: From f1f404d62d9d45b06380762641edf5deb1e35122 Mon Sep 17 00:00:00 2001 From: Charlie Bouthoorn Date: Wed, 27 Jan 2016 16:55:31 +0100 Subject: [PATCH 293/495] Update build.js Fixes https://github.com/noseglid/atom-build/issues/302 --- lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/build.js b/lib/build.js index b55035e1..53eb5beb 100644 --- a/lib/build.js +++ b/lib/build.js @@ -294,7 +294,7 @@ export default { }); let projectPath = projectPaths[0]; - if (editor && 'untitled' !== editor.getTitle()) { + if (editor && (undefined !== editor.getPath())) { const activeFile = fs.realpathSync(editor.getPath()); const activeFilePath = path.dirname(activeFile); projectPath = _.find(projectPaths, (p) => activeFilePath && activeFilePath.startsWith(p)); @@ -462,7 +462,7 @@ export default { unsavedTextEditors() { return atom.workspace.getTextEditors().filter((textEditor) => { - return textEditor.isModified() && ('untitled' !== textEditor.getTitle()); + return textEditor.isModified() && (undefined !== textEditor.getPath()); }); }, From 597af58d229bc2ab80dd9333704098a4ba694ce6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 29 Jan 2016 20:52:25 +0100 Subject: [PATCH 294/495] Trashcan only clears output The trashcan clears the output so far, but shouldn't stop build timer or spinning cogwheel. --- lib/build-view.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index 9342c92a..ecef0ce9 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -34,7 +34,7 @@ export default class BuildView extends View { this.div({ class: 'control-container pull-right opaque-hover' }, () => { this.button({ class: 'btn btn-default icon icon-x', click: 'close' }); this.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' }); - this.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clear' }); + this.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clearOutput' }); this.button({ class: 'btn btn-default icon icon-zap', click: 'build', title: 'Build current project' }); this.div({ class: 'title new-row', outlet: 'title' }, () => { this.span({ class: 'icon icon-gear', outlet: 'gear' }); @@ -118,10 +118,8 @@ export default class BuildView extends View { reset() { clearTimeout(this.titleTimer); this.buildTimer.text(BuildView.initialTimerText()); - this.buffer = new Buffer(0); - this.links = []; this.titleTimer = 0; - this.output.empty(); + this.clearOutput(); this.title.removeClass('success error'); this.gear.removeClass('spin spin-flash'); @@ -144,9 +142,10 @@ export default class BuildView extends View { this.isAttached() ? this.detach(true) : this.attach(true); } - clear() { - this.reset(); - this.attach(); + clearOutput() { + this.buffer = new Buffer(0); + this.links = []; + this.output.empty(); } build() { From 5d6a9ca522e5e77348ab9b7b31a2c3649e4bcc95 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 29 Jan 2016 20:53:34 +0100 Subject: [PATCH 295/495] StatusBar: Switching pane doesn't clear statusbar The statusbar icon will remain as long as the same project root is kept. Also, going to a repo with no build target will now clear the displayed active build target. --- lib/status-bar-view.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/status-bar-view.js b/lib/status-bar-view.js index 7b75d697..46e8b5bd 100644 --- a/lib/status-bar-view.js +++ b/lib/status-bar-view.js @@ -58,8 +58,12 @@ export default class StatusBarView extends View { } setTarget(t) { + if (this.target === t) { + return; + } + this.target = t; - this.message.text(t); + this.message.text(t || ''); this.setClasses(); } From 9708c2dd12b9ff4421e66b3158b4a811fa9838f5 Mon Sep 17 00:00:00 2001 From: Dmytro Kyrychuk Date: Sun, 31 Jan 2016 11:01:48 +0200 Subject: [PATCH 296/495] Allow to specify a command name for a target --- lib/build.js | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/build.js b/lib/build.js index 53eb5beb..3300ad07 100644 --- a/lib/build.js +++ b/lib/build.js @@ -3,7 +3,7 @@ import fs from 'fs'; import path from 'path'; import _ from 'lodash'; -import { Disposable } from 'atom'; +import { Disposable, CompositeDisposable } from 'atom'; import kill from 'tree-kill'; import Grim from 'grim'; @@ -20,6 +20,7 @@ import providerLegacy from './provider-legacy'; export default { config: config, + targetsSubscriptions: null, activate() { if (!/^win/.test(process.platform)) { @@ -139,8 +140,7 @@ export default { args: [], cwd: cwd, sh: true, - errorMatch: '', - dispose: Function.prototype + errorMatch: '' }; }, @@ -207,23 +207,26 @@ export default { this.activeTarget[p] = settings[0] ? settings[0].name : undefined; } - this.targets[p].forEach(target => target.dispose()); + // CompositeDisposable cannot be reused, so we must create a new instance on every refresh + this.targetsSubscriptions && this.targetsSubscriptions.dispose(); + this.targetsSubscriptions = new CompositeDisposable(); settings.forEach((setting, index) => { - if (!setting.keymap) { + if (!setting.atomCommandName) { return; } - GoogleAnalytics.sendEvent('keymap', 'registered', setting.keymap); - const commandName = 'build:trigger:' + setting.name; - const keymapSpec = { 'atom-workspace, atom-text-editor': {} }; - keymapSpec['atom-workspace, atom-text-editor'][setting.keymap] = commandName; - const keymapDispose = atom.keymaps.add(setting.name, keymapSpec); - const commandDispose = atom.commands.add('atom-workspace', commandName, this.build.bind(this, 'trigger')); - settings[index].dispose = () => { - keymapDispose.dispose(); - commandDispose.dispose(); - }; + const subscriptions = new CompositeDisposable(); + subscriptions.add(atom.commands.add('atom-workspace', setting.atomCommandName, this.build.bind(this, 'trigger'))); + + if (setting.keymap) { + GoogleAnalytics.sendEvent('keymap', 'registered', setting.keymap); + const keymapSpec = { 'atom-workspace, atom-text-editor': {} }; + keymapSpec['atom-workspace, atom-text-editor'][setting.keymap] = setting.atomCommandName; + subscriptions.add(atom.keymaps.add(setting.name, keymapSpec)); + } + + this.targetsSubscriptions.add(subscriptions); }); this.targets[p] = settings; @@ -311,16 +314,19 @@ export default { return value; }, - startNewBuild(source, targetName) { + startNewBuild(source, atomCommandName) { const p = this.activePath(); - targetName = targetName || this.activeTarget[p]; Promise.resolve(this.targets[p]).then(targets => { if (!targets || 0 === targets.length) { throw new BuildError('No eligible build target.', 'No configuration to build this project exists.'); } - const target = targets.find(t => t.name === targetName); + let target = targets.find(t => t.atomCommandName === atomCommandName); + if (!target) { + const targetName = this.activeTarget[p]; + target = targets.find(t => t.name === targetName); + } GoogleAnalytics.sendEvent('build', 'triggered'); if (!target.exec) { @@ -437,7 +443,7 @@ export default { clearTimeout(this.finishedTimer); this.doSaveConfirm(this.unsavedTextEditors(), () => { - const next = this.startNewBuild.bind(this, source, event ? event.type.substr(14) : null); + const next = this.startNewBuild.bind(this, source, event ? event.type : null); this.child ? this.abort(next) : next(); }); }, From a1acc02625db539214d80639cf138a0b4dd6f453 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 14:22:06 +0100 Subject: [PATCH 297/495] Make it work with custom file too --- lib/atom-build.js | 1 + lib/build.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index e822d5eb..dd1cf6e5 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -31,6 +31,7 @@ function createBuildConfig(build, name) { cwd: build.cwd, sh: build.sh, errorMatch: build.errorMatch, + atomCommandName: build.atomCommandName, keymap: build.keymap }; } diff --git a/lib/build.js b/lib/build.js index 3300ad07..804a0c38 100644 --- a/lib/build.js +++ b/lib/build.js @@ -212,8 +212,8 @@ export default { this.targetsSubscriptions = new CompositeDisposable(); settings.forEach((setting, index) => { - if (!setting.atomCommandName) { - return; + if (setting.keymap && !setting.atomCommandName) { + setting.atomCommandName = `build:trigger:${setting.name}`; } const subscriptions = new CompositeDisposable(); From ccb63523c15a049f109e4d6aadb94e1893b783f7 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 14:22:35 +0100 Subject: [PATCH 298/495] Added specs for atom command name --- spec/build-atomCommandName-spec.js | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 spec/build-atomCommandName-spec.js diff --git a/spec/build-atomCommandName-spec.js b/spec/build-atomCommandName-spec.js new file mode 100644 index 00000000..ee6aafaa --- /dev/null +++ b/spec/build-atomCommandName-spec.js @@ -0,0 +1,62 @@ +'use babel'; + +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; + +fdescribe('AtomCommandName', () => { + let directory = null; + let workspaceElement = null; + + temp.track(); + + beforeEach(() => { + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })); + atom.project.setPaths([ directory ]); + + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + atom.config.set('build.notificationOnRefresh', true); + + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + + runs(() => { + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + }); + + waitsForPromise(() => { + return atom.packages.activatePackage('build'); + }); + }); + + afterEach(() => { + fs.removeSync(directory); + }); + + describe('when atomCommandName is specified in build config', () => { + it('it should register that command to atom', () => { + fs.writeFileSync(`${directory}/.atom-build.json`, JSON.stringify({ + name: 'The default build', + cmd: 'echo default', + atomCommandName: 'someProvider:customCommand' + })); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + + runs(() => atom.commands.dispatch(workspaceElement, 'someProvider:customCommand')); + + waitsFor(() => { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(() => { + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); + }); + }); + }); +}); From ba3cc963d03fcea8e3b6f52384fdc36aa37e6dd9 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 14:22:47 +0100 Subject: [PATCH 299/495] Updated README with * Atom Command Name * YAML custom file support --- README.md | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 740fd05e..19fbe340 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ [![Package version](https://img.shields.io/apm/v/build.svg?style=flat-square)](https://atom.io/packages/build) [![Travis.ci Shield](https://img.shields.io/travis/noseglid/atom-build/master.svg?style=flat-square&label=travis%20ci)](https://travis-ci.org/noseglid/atom-build) -[![AppVeyor Shield](https://img.shields.io/appveyor/ci/noseglid/atom-build/master.svg?style=flat-square&label=appveyor -)](https://ci.appveyor.com/project/noseglid/atom-build) +[![AppVeyor Shield](https://img.shields.io/appveyor/ci/noseglid/atom-build/master.svg?style=flat-square&label=appveyor )](https://ci.appveyor.com/project/noseglid/atom-build) [![Gitter chat](https://img.shields.io/badge/gitter-noseglid%2Fatom--build-24CE66.svg?style=flat-square)](https://gitter.im/noseglid/atom-build) [![Slack Badge](https://img.shields.io/badge/chat-atom.io%20slack-ff69b4.svg?style=flat-square)](http://atom-slack.herokuapp.com/) @@ -38,10 +37,15 @@ Read more about building your own provider in [the create provider documentation ### Specifying a custom build command -If no build tool is enough to suit your needs, you can create a file named `.atom-build.json` -(it may also be `.atom-build.cson` if [CoffeeScript Object Notation](https://github.com/bevry/cson) is -your cup of tea). -in your project root, and specify exactly how your project is built: +If no build tool is enough to suit your needs, you can create a custom build command. +Supported formats and the name of the configuration file is + + * JSON: `.atom-build.json` + * CSON: `.atom-build.cson` + * YAML: `.atom-build.yml` + +Pick your favorite format, save that file in your project root, and specify exactly +how your project is built { "cmd": "", @@ -59,6 +63,7 @@ in your project root, and specify exactly how your project is built: "^regexp2$" ], "keymap": "", + "atomCommandName": "namespace:command", "targets": { "": { "cmd": "", @@ -72,20 +77,24 @@ executable is not in your path, either fully qualify it or specify the path in you environment (e.g. by setting the `PATH` var appropriately on UNIX-like systems). +If `sh` is true, it will use a shell (e.g. `/bin/sh -c`) on unix/linux, and command (`cmd /C`) +on windows. + #### Configuration options -Option | Required | Description --------------|----------------|----------------------- -`cmd` | **[required]** | The executable command -`name` | *[optional]* | The name of the targets. Viewed in the targets list (toggled by `build:select-active-target`). -`args` | *[optional]* | An array of arguments for the command -`sh` | *[optional]* | If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. -`cwd` | *[optional]* | The working directory for the command. E.g. what `.` resolves to. -`env` | *[optional]* | An object of environment variables and their values to set -`errorMatch` | *[optional]* | A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. -`keymap` | *[optional]* | A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. -`targets` | *[optional]* | Additional targets which can be used to build variations of your project. +Option | Required | Description +------------------|----------------|----------------------- +`cmd` | **[required]** | The executable command +`name` | *[optional]* | The name of the target. Viewed in the targets list (toggled by `build:select-active-target`). +`args` | *[optional]* | An array of arguments for the command +`sh` | *[optional]* | If `true`, the combined command and arguments will be passed to `/bin/sh`. Default `true`. +`cwd` | *[optional]* | The working directory for the command. E.g. what `.` resolves to. +`env` | *[optional]* | An object of environment variables and their values to set +`errorMatch` | *[optional]* | A (list of) regular expressions to match output to a file, row and col. See [Error matching](#error-match) for details. +`keymap` | *[optional]* | A keymap string as defined by [`Atom`](https://atom.io/docs/latest/behind-atom-keymaps-in-depth). Pressing this key combination will trigger the target. Examples: `ctrl-alt-k` or `cmd-U`. +`atomCommandName` | *[optional]* | Command name to register which should be on the form of `namespace:command`. Read more about [Atom CommandRegistry](https://atom.io/docs/api/v1.4.1/CommandRegistry). The command will be available in the command palette and can be trigger from there. If this is returned by a build provider, the command can programatically be triggered by [dispatching](https://atom.io/docs/api/v1.4.1/CommandRegistry#instance-dispatch). +`targets` | *[optional]* | Additional targets which can be used to build variations of your project. #### Replacements From 95a7dd1b1ed7607584b5d3c292603a54e1f54cc1 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 14:27:07 +0100 Subject: [PATCH 300/495] Don't commit focused specs >_< --- spec/build-atomCommandName-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/build-atomCommandName-spec.js b/spec/build-atomCommandName-spec.js index ee6aafaa..68d33df9 100644 --- a/spec/build-atomCommandName-spec.js +++ b/spec/build-atomCommandName-spec.js @@ -4,7 +4,7 @@ import fs from 'fs-extra'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; -fdescribe('AtomCommandName', () => { +describe('AtomCommandName', () => { let directory = null; let workspaceElement = null; From e4dc334edf588b225388a54fd78bd24f8363aec5 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 17:51:07 +0100 Subject: [PATCH 301/495] Fixed specs when running on windows in preparation for running them on appveyor --- spec/build-confirm-spec.js | 7 ++-- spec/build-error-match-spec.js | 3 +- spec/build-keymap-spec.js | 3 +- spec/build-spec.js | 32 +++++++++++++------ spec/build-view-spec.js | 17 +++++++--- ...build.error-match-multiple-errorMatch.json | 2 +- ...atom-build.error-match-multiple-first.json | 2 +- .../.atom-build.error-match-multiple.json | 2 +- .../.atom-build.error-match-no-file.json | 4 +-- .../.atom-build.error-match-no-line-col.json | 2 +- spec/fixture/.atom-build.error-match.json | 2 +- 11 files changed, 51 insertions(+), 25 deletions(-) diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index f39a59b0..abeb6967 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -8,6 +8,7 @@ import specHelpers from 'atom-build-spec-helpers'; describe('Confirm', () => { let directory = null; let workspaceElement = null; + const cat = process.platform === 'win32' ? 'type' : 'cat'; temp.track(); @@ -135,7 +136,7 @@ describe('Confirm', () => { fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'cat catme' + cmd: `${cat} catme` })); waitsForPromise(() => { @@ -173,7 +174,7 @@ describe('Confirm', () => { fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'cat catme' + cmd: `${cat} catme` })); waitsForPromise(() => { @@ -215,7 +216,7 @@ describe('Confirm', () => { fs.writeFileSync(directory + 'catme', 'Surprising is the passing of time but not so, as the time of passing.'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'cat catme' + cmd: `${cat} catme` })); waitsForPromise(() => { diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index e9db36dd..3c859119 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -1,6 +1,7 @@ 'use babel'; import fs from 'fs-extra'; +import path from 'path'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; @@ -19,7 +20,7 @@ describe('Error Match', () => { temp.track(); beforeEach(() => { - directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + path.sep; atom.project.setPaths([ directory ]); atom.config.set('build.buildOnSave', false); diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index f9ba9950..e21f3423 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -1,6 +1,7 @@ 'use babel'; import fs from 'fs-extra'; +import path from 'path'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; @@ -11,7 +12,7 @@ describe('Keymap', () => { temp.track(); beforeEach(() => { - directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + path.sep; atom.project.setPaths([ directory ]); atom.config.set('build.buildOnSave', false); diff --git a/spec/build-spec.js b/spec/build-spec.js index 1b0ee8bc..7cf84073 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -1,6 +1,7 @@ 'use babel'; import fs from 'fs-extra'; +import path from 'path'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; @@ -15,6 +16,8 @@ describe('Build', () => { let directory = null; let workspaceElement = null; + const sleep = (duration) => process.platform === 'win32' ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; + const cat = () => process.platform === 'win32' ? 'type' : 'cat' temp.track(); @@ -35,7 +38,7 @@ describe('Build', () => { return specHelpers.vouch(temp.mkdir, 'atom-build-spec-').then( (dir) => { return specHelpers.vouch(fs.realpath, dir); }).then( (dir) => { - directory = dir + '/'; + directory = dir + path.sep; atom.project.setPaths([ directory ]); return atom.packages.activatePackage('build'); }); @@ -97,7 +100,7 @@ describe('Build', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo "Building, this will take some time..." && sleep 30 && echo "Done!"' + cmd: `echo "Building, this will take some time..." && ${sleep(30)} && echo "Done!"` })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -178,7 +181,10 @@ describe('Build', () => { it('should show the build window', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ + cmd: cat(), + args: [ '.atom-build.json' ] + })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -191,7 +197,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"args":\[".atom-build.json"\]/); }); }); @@ -236,6 +242,8 @@ describe('Build', () => { }); it('should not show sh message if sh is false', () => { + if (process.platform === 'win32') return; + expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', fs.readFileSync(shFalseAtomBuildFile)); @@ -367,7 +375,6 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); const output = workspaceElement.querySelector('.build .output').textContent; - expect(output.indexOf('PROJECT_PATH=' + directory.substring(0, -1))).not.toBe(-1); expect(output.indexOf('FILE_ACTIVE=' + directory + '.atom-build.json')).not.toBe(-1); expect(output.indexOf('FROM_ENV=' + directory + '.atom-build.json')).not.toBe(-1); @@ -461,7 +468,11 @@ describe('Build', () => { atom.project.addPath(directory2); expect(workspaceElement.querySelector('.build')).not.toExist(); - fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); + fs.writeFileSync(directory2 + '.atom-build.json', JSON.stringify({ + cmd: cat(), + args: [ '.atom-build.json' ] + })); + waitsForPromise(() => { return Promise.all([ specHelpers.refreshAwaitTargets(), @@ -481,13 +492,16 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"args":\[".atom-build.json"\]/); }); }); it('should scan new project roots when they are added', () => { const directory2 = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; - fs.writeFileSync(directory2 + '.atom-build.json', fs.readFileSync(goodAtomBuildfile)); + fs.writeFileSync(directory2 + '.atom-build.json', JSON.stringify({ + cmd: cat(), + args: [ '.atom-build.json' ] + })); atom.project.addPath(directory2); @@ -508,7 +522,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"cmd": "dd"/); + expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"args":\[".atom-build.json"\]/); }); }); }); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 68a836b8..a02475b8 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -1,12 +1,14 @@ 'use babel'; import fs from 'fs-extra'; +import os from 'os'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; describe('BuildView', () => { let directory = null; let workspaceElement = null; + const sleep = (duration) => process.platform === 'win32' ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; temp.track(); @@ -45,6 +47,8 @@ describe('BuildView', () => { describe('when output from build command should be viewed', () => { it('should color output according to ansi escape codes', () => { + if (process.platform === 'win32') return; + fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'printf "\\033[31mHello\\e[0m World"' })); @@ -65,7 +69,9 @@ describe('BuildView', () => { it('should output data even if no line break exists', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'printf "data without linebreak"' + cmd: 'node', + args: [ '-e', 'process.stdout.write(\'data without linebreak\');' ], + sh: false })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -84,7 +90,9 @@ describe('BuildView', () => { it('should only break the line when an actual newline character appears', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'node -e \'process.stdout.write("same"); setTimeout(function() { process.stdout.write(" line\\n") }, 200);\'' + cmd: 'node', + args: [ '-e', 'process.stdout.write(\'same\'); setTimeout(function() { process.stdout.write(\' line\\n\') }, 200);' ], + sh: false })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -133,7 +141,7 @@ describe('BuildView', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo "Building, this will take some time..." && sleep 30 && echo "Done!"' + cmd: `echo "Building, this will take some time..." && ${sleep(30)} && echo "Done!"` })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -284,8 +292,9 @@ describe('BuildView', () => { it('should keep the build scrolled to bottom', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); + const args = Array(50).join('All work and no play'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo "a\nb\nc\nd\ne\nf\ng\nh\ni\nj" && exit 1' + cmd: `echo "${args}" && exit 1` })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); diff --git a/spec/fixture/.atom-build.error-match-multiple-errorMatch.json b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json index 8f6aa14f..dd1a43be 100755 --- a/spec/fixture/.atom-build.error-match-multiple-errorMatch.json +++ b/spec/fixture/.atom-build.error-match-multiple-errorMatch.json @@ -1,5 +1,5 @@ { - "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:1,column::::2'\nfile:.atom-build.json,line:2,column:5' && return 1", + "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:1,column::::2'\nfile:.atom-build.json,line:2,column:5' && exit 1", "errorMatch": [ "file:(?[^,]+),line:(?\\d+),column:(?\\d+)", "file:(?[^,]+),line:(?\\d+),column::::(?\\d+)" diff --git a/spec/fixture/.atom-build.error-match-multiple-first.json b/spec/fixture/.atom-build.error-match-multiple-first.json index 9e8d77b5..0c8b25dd 100644 --- a/spec/fixture/.atom-build.error-match-multiple-first.json +++ b/spec/fixture/.atom-build.error-match-multiple-first.json @@ -1,4 +1,4 @@ { - "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:2,column:5\nfile:.atom-build.json,line:1,column:1' && return 1", + "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:2,column:5\nfile:.atom-build.json,line:1,column:1' && exit 1", "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)" } diff --git a/spec/fixture/.atom-build.error-match-multiple.json b/spec/fixture/.atom-build.error-match-multiple.json index f4e44d4b..c336e998 100644 --- a/spec/fixture/.atom-build.error-match-multiple.json +++ b/spec/fixture/.atom-build.error-match-multiple.json @@ -1,4 +1,4 @@ { - "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:2,column:5' && return 1", + "cmd": "echo 'file:.atom-build.json,line:3,column:8\nfile:.atom-build.json,line:2,column:5' && exit 1", "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)" } diff --git a/spec/fixture/.atom-build.error-match-no-file.json b/spec/fixture/.atom-build.error-match-no-file.json index 5ddcd05c..a9ab0023 100644 --- a/spec/fixture/.atom-build.error-match-no-file.json +++ b/spec/fixture/.atom-build.error-match-no-file.json @@ -1,4 +1,4 @@ { - "cmd": "echo 'file:black-hole,line:3,column:8' && return 1", + "cmd": "echo 'file:black-hole,line:3,column:8' && exit 1", "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)" -} \ No newline at end of file +} diff --git a/spec/fixture/.atom-build.error-match-no-line-col.json b/spec/fixture/.atom-build.error-match-no-line-col.json index e72fa04d..804d7c8e 100644 --- a/spec/fixture/.atom-build.error-match-no-line-col.json +++ b/spec/fixture/.atom-build.error-match-no-line-col.json @@ -1,4 +1,4 @@ { - "cmd": "echo 'file:.atom-build.json,line:3,column:8' && return 1", + "cmd": "echo 'file:.atom-build.json,line:3,column:8' && exit 1", "errorMatch": "file:(?[^,]+)" } diff --git a/spec/fixture/.atom-build.error-match.json b/spec/fixture/.atom-build.error-match.json index a8d1434f..480ad16e 100644 --- a/spec/fixture/.atom-build.error-match.json +++ b/spec/fixture/.atom-build.error-match.json @@ -1,4 +1,4 @@ { - "cmd": "echo 'file:.atom-build.json,line:3,column:8' && return 1", + "cmd": "echo 'file:.atom-build.json,line:3,column:8' && exit 1", "errorMatch": "file:(?[^,]+),line:(?\\d+),column:(?\\d+)" } From b07b3bc95192f5d0bdb37e43c7b0b1490629b364 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 19:23:13 +0100 Subject: [PATCH 302/495] Fixed linting errors --- spec/build-spec.js | 2 +- spec/build-view-spec.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/build-spec.js b/spec/build-spec.js index 7cf84073..b6024a28 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -17,7 +17,7 @@ describe('Build', () => { let directory = null; let workspaceElement = null; const sleep = (duration) => process.platform === 'win32' ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; - const cat = () => process.platform === 'win32' ? 'type' : 'cat' + const cat = () => process.platform === 'win32' ? 'type' : 'cat'; temp.track(); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index a02475b8..083ff6d7 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -1,7 +1,6 @@ 'use babel'; import fs from 'fs-extra'; -import os from 'os'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; From 3ae71d2d5a6175d5d0173c90cdbfaa28de45cbe8 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 19:27:38 +0100 Subject: [PATCH 303/495] Added appveyor configuration --- appveyor.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..bf9e6ff1 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,21 @@ +version: "{build}" +os: Windows Server 2012 R2 + +environment: + nodejs_version: "5" + +test: off +deploy: off + +init: + - cmd: rd /s /q %CHOCOLATEYINSTALL% + - ps: iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) + +install: + - cinst atom -y + - cd %APPVEYOR_BUILD_FOLDER% + - "%LOCALAPPDATA%/atom/bin/apm install" + +build_script: + - cd %APPVEYOR_BUILD_FOLDER% + - "%LOCALAPPDATA%/atom/bin/apm test --path %LOCALAPPDATA%/atom/bin/atom.cmd" From 15bf20dafbeb78ad1f4272dd5126f9e49eb3c964 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 21:11:52 +0100 Subject: [PATCH 304/495] Download and install Atom to get latest version --- appveyor.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index bf9e6ff1..d1912072 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,21 +1,19 @@ -version: "{build}" -os: Windows Server 2012 R2 - environment: nodejs_version: "5" +version: "{build}" +os: Windows Server 2012 R2 + test: off deploy: off -init: - - cmd: rd /s /q %CHOCOLATEYINSTALL% - - ps: iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) - install: - - cinst atom -y - - cd %APPVEYOR_BUILD_FOLDER% - - "%LOCALAPPDATA%/atom/bin/apm install" + - appveyor DownloadFile https://atom.io/download/windows -FileName AtomSetup.exe + - AtomSetup.exe /silent build_script: - cd %APPVEYOR_BUILD_FOLDER% - - "%LOCALAPPDATA%/atom/bin/apm test --path %LOCALAPPDATA%/atom/bin/atom.cmd" + - SET PATH=%LOCALAPPDATA%\atom\bin;%PATH% + - apm clean + - apm install + - apm test \ No newline at end of file From 79222651a38c5d9e802c322ecba5af44814fddb1 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 31 Jan 2016 19:33:13 +0100 Subject: [PATCH 305/495] Spec timers adjusted to work on appveyor --- spec/build-confirm-spec.js | 5 +++-- spec/build-error-match-spec.js | 13 +++++++------ spec/build-spec.js | 21 +++++++++++---------- spec/build-view-spec.js | 4 ++-- spec/build-visible-spec.js | 11 ++++++----- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index abeb6967..0143e2c3 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -9,6 +9,7 @@ describe('Confirm', () => { let directory = null; let workspaceElement = null; const cat = process.platform === 'win32' ? 'type' : 'cat'; + const waitTime = process.env.CI ? 2400 : 200; temp.track(); @@ -240,7 +241,7 @@ describe('Confirm', () => { workspaceElement.querySelector('button[click="cancel"]').click(); }); - waits(2); + waits(waitTime); runs(() => { const editor = atom.workspace.getActiveTextEditor(); @@ -281,7 +282,7 @@ describe('Confirm', () => { atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - waits(200); // Everything is the same so we can't know when second build:trigger has been handled + waits(waitTime); // Everything is the same so we can't know when second build:trigger has been handled runs(() => { expect(workspaceElement.querySelectorAll('.build-confirm').length).toEqual(1); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index 3c859119..b2efcd04 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -16,6 +16,7 @@ describe('Error Match', () => { let directory = null; let workspaceElement = null; + const waitTime = process.env.CI ? 2400 : 200; temp.track(); @@ -414,20 +415,20 @@ describe('Error Match', () => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waits(100); + waits(waitTime); let firstScrollTop; runs(() => { firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waits(100); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waits(100); + waits(waitTime); runs(() => { /* Should wrap around to first match */ expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); @@ -451,20 +452,20 @@ describe('Error Match', () => { atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waits(100); + waits(waitTime); let firstScrollTop; runs(() => { firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; atom.commands.dispatch(workspaceElement, 'build:error-match'); }); - waits(100); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); - waits(100); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); }); diff --git a/spec/build-spec.js b/spec/build-spec.js index b6024a28..e5060e6e 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -18,6 +18,7 @@ describe('Build', () => { let workspaceElement = null; const sleep = (duration) => process.platform === 'win32' ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; const cat = () => process.platform === 'win32' ? 'type' : 'cat'; + const waitTime = process.env.CI ? 2400 : 200; temp.track(); @@ -137,7 +138,7 @@ describe('Build', () => { atom.commands.dispatch(workspaceElement, 'build:trigger'); /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ - waits(200); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); @@ -163,13 +164,14 @@ describe('Build', () => { return workspaceElement.querySelector('.build .title').classList.contains('success'); }); + waits(50); + runs(() => { expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1); atom.commands.dispatch(workspaceElement, 'build:trigger'); }); - /* Give it some time here. There's nothing to probe for as we expect the exact same state when done. */ - waits(200); + waits(50); runs(() => { expect(workspaceElement.querySelectorAll('.bottom.tool-panel.panel-bottom').length).toBe(1); @@ -334,7 +336,7 @@ describe('Build', () => { })); }); - waits(100); + waits(waitTime); runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); @@ -454,7 +456,7 @@ describe('Build', () => { editor.save(); }); - waits(200); + waits(waitTime); runs(() => { expect(atom.notifications.getNotifications().length).toEqual(0); @@ -503,12 +505,11 @@ describe('Build', () => { args: [ '.atom-build.json' ] })); - atom.project.addPath(directory2); + waitsForPromise(() => atom.workspace.open(directory2 + '/main.c')); + + runs(() => atom.project.addPath(directory2)); - waitsForPromise(() => Promise.all([ - atom.workspace.open(directory2 + '/main.c'), - specHelpers.awaitTargets() - ])); + waitsForPromise(() => specHelpers.awaitTargets()); runs(() => { atom.workspace.getActiveTextEditor().save(); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 083ff6d7..1f256b7c 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -147,9 +147,9 @@ describe('BuildView', () => { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - // Let build run for 1.2 second. This should set the timer at "at least" 1.2 + // Let build run for 1.5 second. This should set the timer at "at least" 1.5 // which is expected below. If this waits longer than 2000 ms, we're in trouble. - waits(1200); + waits(1500); runs(() => { expect(workspaceElement.querySelector('.build-timer').textContent).toMatch(/1.\d/); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index bbf6f289..adcbecb6 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -7,6 +7,7 @@ import specHelpers from 'atom-build-spec-helpers'; describe('Visible', () => { let directory = null; let workspaceElement = null; + const waitTime = process.env.CI ? 2400 : 200; temp.track(); @@ -90,7 +91,7 @@ describe('Visible', () => { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); /* Give it some reasonable time to show itself if there is a bug */ - waits(200); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); @@ -103,7 +104,7 @@ describe('Visible', () => { }); // .atom-build.json is updated asynchronously... give it some time - waits(200); + waits(waitTime); runs(() => { atom.commands.dispatch(workspaceElement, 'build:trigger'); @@ -132,7 +133,7 @@ describe('Visible', () => { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); /* Give it some reasonable time to show itself if there is a bug */ - waits(200); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); @@ -151,7 +152,7 @@ describe('Visible', () => { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); /* Give it some reasonable time to show itself if there is a bug */ - waits(200); + waits(waitTime); runs(() => { expect(workspaceElement.querySelector('.build')).not.toExist(); @@ -169,7 +170,7 @@ describe('Visible', () => { runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - waits(200); // Let build finish. Since UI component is not visible yet, there's nothing to poll. + waits(waitTime); // Let build finish. Since UI component is not visible yet, there's nothing to poll. runs(() => { atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); From b957dbb81389b9728afff26e4b161ade60583557 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Feb 2016 19:34:21 +0100 Subject: [PATCH 306/495] Fixed linting issue This is an issue with escope which is a dependency for babel-eslint. See https://github.com/babel/babel-eslint/issues/243 for more info --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fb158b8f..4ec79e9b 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,11 @@ "xregexp": "^2.0.0" }, "devDependencies": { - "eslint-config-atom-build": "^1.0.0", "atom-build-spec-helpers": "^0.3.0", "babel-eslint": "^4.1.5", + "escope": "3.3.0", "eslint": "^1.10.1", + "eslint-config-atom-build": "^2.0.0", "fs-extra": "^0.23.0", "temp": "^0.8.1" }, From bbc300763598eb7656e37e3e315d37fcdfadc2bc Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Feb 2016 19:51:40 +0100 Subject: [PATCH 307/495] Prepare 0.54.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4ec79e9b..eeac0cc7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.53.0", + "version": "0.54.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 9cfc410da3c4f576c34eecd0d102d11297489f84 Mon Sep 17 00:00:00 2001 From: Dmytro Kyrychuk Date: Mon, 1 Feb 2016 22:15:01 +0200 Subject: [PATCH 308/495] Have separate disposable for each project --- lib/build.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/build.js b/lib/build.js index fd4c1ed7..0ec04f30 100644 --- a/lib/build.js +++ b/lib/build.js @@ -20,7 +20,6 @@ import providerLegacy from './provider-legacy'; export default { config: config, - targetsSubscriptions: null, activate() { if (!/^win/.test(process.platform)) { @@ -37,6 +36,7 @@ export default { this.targets = {}; this.activeTarget = {}; this.targetsLoading = {}; + this.targetsSubscriptions = {}; this.stdout = new Buffer(0); this.stderr = new Buffer(0); @@ -208,8 +208,8 @@ export default { } // CompositeDisposable cannot be reused, so we must create a new instance on every refresh - this.targetsSubscriptions && this.targetsSubscriptions.dispose(); - this.targetsSubscriptions = new CompositeDisposable(); + this.targetsSubscriptions[p] && this.targetsSubscriptions[p].dispose(); + this.targetsSubscriptions[p] = new CompositeDisposable(); settings.forEach((setting, index) => { if (setting.keymap && !setting.atomCommandName) { @@ -226,7 +226,7 @@ export default { subscriptions.add(atom.keymaps.add(setting.name, keymapSpec)); } - this.targetsSubscriptions.add(subscriptions); + this.targetsSubscriptions[p].add(subscriptions); }); this.targets[p] = settings; From 624a02caa3e9fcd5e349be35d7026fc7340fa0f7 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Feb 2016 21:29:12 +0100 Subject: [PATCH 309/495] Add release notes link to README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 19fbe340..66ccd959 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # Atom Build package + +[Release notes](https://github.com/noseglid/atom-build/releases) + [![Plugin installs](https://img.shields.io/apm/dm/build.svg?style=flat-square)](https://atom.io/packages/build) [![Package version](https://img.shields.io/apm/v/build.svg?style=flat-square)](https://atom.io/packages/build) From 67de0499676e02bcbb051cd2581d13fa5d6febc2 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Feb 2016 22:10:09 +0100 Subject: [PATCH 310/495] More gifs in README --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66ccd959..166d428d 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,14 @@ Automatically build your project inside your new favorite editor, Atom. * `cmd-alt-t` / `ctrl-alt-t` / `f7` Displays the available build targets. * `escape` terminates build / closes the build window. -![work work](https://noseglid.github.io/atom-build.gif) +#### Builds your project - configure it your way +![work work](https://noseglid.github.io/build.gif) + +#### Extract targets - here used with [build-gulp](https://github.com/AtomBuild/atom-build-gulp). +![targets](https://noseglid.github.io/targets.gif) + +#### Match errors and go directly to offending code +![error matching](https://noseglid.github.io/error-match.gif) ## Build providers The best way to use this `build` packages is via a build provider. From 632ef90fae665abaf8109ede6243a95b0b9f3254 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Mon, 1 Feb 2016 22:11:11 +0100 Subject: [PATCH 311/495] Prepare 0.54.1 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eeac0cc7..921e4fd1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.54.0", + "version": "0.54.1", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From e749ce8a74ffbdad9c12e9238882e2ee94af22df Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Fri, 12 Feb 2016 15:14:16 +0100 Subject: [PATCH 312/495] :arrow_up: tree-kill Newer version of tree-kill supports darwin. Fixes #276 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 921e4fd1..68d669eb 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "js-yaml": "^3.4.6", "lodash": "^3.8.0", "node-uuid": "^1.4.3", - "tree-kill": "^0.1.1", + "tree-kill": "^1.0.0", "xregexp": "^2.0.0" }, "devDependencies": { From 525d71ed5855ebdb7ce6c65e04ff47fd3ef79205 Mon Sep 17 00:00:00 2001 From: John Ogle Date: Thu, 18 Feb 2016 14:51:50 -0800 Subject: [PATCH 313/495] Properly support spaces in arguments on Windows --- lib/build.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/build.js b/lib/build.js index 0ec04f30..3cbd04e1 100644 --- a/lib/build.js +++ b/lib/build.js @@ -343,12 +343,12 @@ export default { const cwd = this.replace(target.cwd, target.env); const isWin = process.platform === 'win32'; const shCmd = isWin ? 'cmd' : '/bin/sh'; - const shCmdArg = isWin ? '/C' : '-c'; + const shCmdArg = isWin ? '/S/C' : '-c'; this.child = require('child_process').spawn( target.sh ? shCmd : exec, - target.sh ? [ shCmdArg, [ path.normalize(exec) ].concat(args).join(' ') ] : args, - { cwd: cwd, env: env } + target.sh ? [ shCmdArg, [ path.normalize(exec) ].concat(isWin ? args.map(arg => '"'+arg+'"') : args).join(' ') ] : args, + { cwd: cwd, env: env, windowsVerbatimArguments: true } ); this.stdout = new Buffer(0); From ef4a3877918d8473352b5962ff31d8de8361239d Mon Sep 17 00:00:00 2001 From: John Ogle Date: Thu, 18 Feb 2016 14:56:43 -0800 Subject: [PATCH 314/495] Fix Travis CI build --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 3cbd04e1..05835efe 100644 --- a/lib/build.js +++ b/lib/build.js @@ -347,7 +347,7 @@ export default { this.child = require('child_process').spawn( target.sh ? shCmd : exec, - target.sh ? [ shCmdArg, [ path.normalize(exec) ].concat(isWin ? args.map(arg => '"'+arg+'"') : args).join(' ') ] : args, + target.sh ? [ shCmdArg, [ path.normalize(exec) ].concat(isWin ? args.map(arg => '"' + arg + '"') : args).join(' ') ] : args, { cwd: cwd, env: env, windowsVerbatimArguments: true } ); From 3b5cf2901819808992a614c7dfc6848c3ba54621 Mon Sep 17 00:00:00 2001 From: John Ogle Date: Fri, 19 Feb 2016 10:08:42 -0800 Subject: [PATCH 315/495] Use cross-spawn when sh is false for better Windows spawning support --- lib/build.js | 22 +++++++++++++++------- package.json | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/build.js b/lib/build.js index 05835efe..6d15c82b 100644 --- a/lib/build.js +++ b/lib/build.js @@ -343,13 +343,21 @@ export default { const cwd = this.replace(target.cwd, target.env); const isWin = process.platform === 'win32'; const shCmd = isWin ? 'cmd' : '/bin/sh'; - const shCmdArg = isWin ? '/S/C' : '-c'; - - this.child = require('child_process').spawn( - target.sh ? shCmd : exec, - target.sh ? [ shCmdArg, [ path.normalize(exec) ].concat(isWin ? args.map(arg => '"' + arg + '"') : args).join(' ') ] : args, - { cwd: cwd, env: env, windowsVerbatimArguments: true } - ); + const shCmdArg = isWin ? '/C' : '-c'; + + if (target.sh) { + this.child = require('child_process').spawn( + shCmd, + [ shCmdArg, [ path.normalize(exec) ].concat(args).join(" ")], + { cwd: cwd, env: env } + ); + } else { + this.child = require('cross-spawn-async').spawn( + exec, + args, + { cwd: cwd, env: env } + ); + } this.stdout = new Buffer(0); this.child.stdout.on('data', (buffer) => { diff --git a/package.json b/package.json index 68d669eb..05b1967c 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "ansi_up": "^1.3.0", "atom-space-pen-views": "^2.0.3", + "cross-spawn": "^2.1.5", "cson-parser": "^1.3.0", "getmac": "^1.0.7", "grim": "^2.0.0", From ba9f12d237aeecb7e7510a19a093447a04e1e9d5 Mon Sep 17 00:00:00 2001 From: Charlie Bouthoorn Date: Fri, 19 Feb 2016 19:45:03 +0100 Subject: [PATCH 316/495] Update build.js Fixed Travis CI build --- lib/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.js b/lib/build.js index 6d15c82b..af201187 100644 --- a/lib/build.js +++ b/lib/build.js @@ -348,7 +348,7 @@ export default { if (target.sh) { this.child = require('child_process').spawn( shCmd, - [ shCmdArg, [ path.normalize(exec) ].concat(args).join(" ")], + [ shCmdArg, [ path.normalize(exec) ].concat(args).join(' ')], { cwd: cwd, env: env } ); } else { From acda1f3fa0982e07551781c9012fb66b9f1df2dc Mon Sep 17 00:00:00 2001 From: John Ogle Date: Fri, 19 Feb 2016 10:57:53 -0800 Subject: [PATCH 317/495] cross-spawn => cross-spawn-async --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 05b1967c..a2ad5b80 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "dependencies": { "ansi_up": "^1.3.0", "atom-space-pen-views": "^2.0.3", - "cross-spawn": "^2.1.5", + "cross-spawn-async": "^2.1.8", "cson-parser": "^1.3.0", "getmac": "^1.0.7", "grim": "^2.0.0", From 01cffc1bc963c9dd1d83f50bec227b5a18c2e931 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 20 Feb 2016 11:32:17 +0100 Subject: [PATCH 318/495] Minor modifications to README --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 166d428d..4ad519b3 100644 --- a/README.md +++ b/README.md @@ -24,28 +24,23 @@ Automatically build your project inside your new favorite editor, Atom. #### Builds your project - configure it your way ![work work](https://noseglid.github.io/build.gif) -#### Extract targets - here used with [build-gulp](https://github.com/AtomBuild/atom-build-gulp). +#### Automatically extract targets - here with [build-gulp](https://github.com/AtomBuild/atom-build-gulp). ![targets](https://noseglid.github.io/targets.gif) #### Match errors and go directly to offending code ![error matching](https://noseglid.github.io/error-match.gif) ## Build providers -The best way to use this `build` packages is via a build provider. -Build providers are plugins to `build` which enables specific build tools (such as `GNU Make`, `gradle` or `gulp`). +** [AtomBuilds homepage](https://atombuild.github.io) holds a comprehensive list of available build providers. ** -[AtomBuilds homepage](https://atombuild.github.io) for a list of build providers. +The best way to use this `build` packages is via a build provider. +Build providers are plugins to `build` which enables specific build tools (such as `GNU Make`, `gradle`, `gulp`, etc). Build providers can be downloaded via Atoms package manager and installed as any other package. -### Creating a build provider -Creating a build provider require very little code in the easiest case, and can -be as complicated as necessary to achieve the correct functionality. -Read more about building your own provider in [the create provider documentation](create-provider.md). - -### Specifying a custom build command +### Specify a custom build command If no build tool is enough to suit your needs, you can create a custom build command. Supported formats and the name of the configuration file is @@ -55,7 +50,7 @@ Supported formats and the name of the configuration file is * YAML: `.atom-build.yml` Pick your favorite format, save that file in your project root, and specify exactly -how your project is built +how your project is built (example in `json`) { "cmd": "", @@ -82,12 +77,12 @@ how your project is built } } -Note that if `sh` is false `cmd` must only be the executable - no arguments here. If the +Note that if `sh` is false `cmd` must only be the executable - no arguments here. If the executable is not in your path, either fully qualify it or specify the path in you environment (e.g. by setting the `PATH` var appropriately on UNIX-like systems). -If `sh` is true, it will use a shell (e.g. `/bin/sh -c`) on unix/linux, and command (`cmd /C`) +If `sh` is true, it will use a shell (e.g. `/bin/sh -c`) on unix/linux, and command (`cmd /S /C`) on windows. @@ -118,6 +113,11 @@ values of `env`. They should all be enclosed in curly brackets `{}` * `{PROJECT_PATH}` - Full path to the root of the project. This is normally the path Atom has as root. E.g `/home/noseglid/github/atom-build` * `{REPO_BRANCH_SHORT}` - Short name of the current active branch (if project is backed by git). E.g `master` or `v0.9.1`. +### Creating a build provider +Creating a build provider require very little code in the easiest case, and can +be as complicated as necessary to achieve the correct functionality. +Read more about building your own provider in [the create provider documentation](create-provider.md). + ## Error matching From 6fbafc40bb940fb76f547b955d0eff8016c86f3e Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sat, 20 Feb 2016 11:32:34 +0100 Subject: [PATCH 319/495] Prepare 0.55.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a2ad5b80..a3513054 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "build", "main": "./lib/build", - "version": "0.54.1", + "version": "0.55.0", "description": "Build your current project, directly from Atom", "repository": "https://github.com/noseglid/atom-build", "license": "MIT", From 633e14dfda965e8d7961a49970f9bc415f083a6f Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Sun, 21 Feb 2016 11:46:05 +0100 Subject: [PATCH 320/495] Allow user to have a global config file in the home directory Big Commit ahead, please read description -> -> This change is simple as modify the isElegible function to also return the home directory as a possible config file directory, core functions do the rest on finding and parsing the config file -> As this affects a core function all the core tests need to be modified to support using the home directory as an elegible directory -> Custom provider spec had been modified to split test between finding a file target and parsing and checking the targets --- lib/atom-build.js | 12 +++++-- spec/build-atomCommandName-spec.js | 5 +++ spec/build-confirm-spec.js | 5 +++ spec/build-error-match-spec.js | 5 +++ spec/build-keymap-spec.js | 5 +++ spec/build-spec.js | 8 +++++ spec/build-targets-spec.js | 8 +++++ spec/build-view-spec.js | 8 +++++ spec/build-visible-spec.js | 8 +++++ spec/custom-provider-spec.js | 51 ++++++++++++++++++++++-------- 10 files changed, 99 insertions(+), 16 deletions(-) diff --git a/lib/atom-build.js b/lib/atom-build.js index dd1cf6e5..f361e9ab 100644 --- a/lib/atom-build.js +++ b/lib/atom-build.js @@ -6,6 +6,7 @@ import _ from 'lodash'; import CSON from 'cson-parser'; import yaml from 'js-yaml'; import EventEmitter from 'events'; +import os from 'os'; function getConfig(file) { const realFile = fs.realpathSync(file); @@ -52,9 +53,14 @@ export default class CustomFile extends EventEmitter { } isEligible() { - this.files = [ '.atom-build.json', '.atom-build.cson', '.atom-build.yml' ] - .map(file => path.join(this.cwd, file)) - .filter(fs.existsSync); + this.files = [ + path.join(this.cwd, '.atom-build.json'), + path.join(this.cwd, '.atom-build.cson'), + path.join(this.cwd, '.atom-build.yml'), + path.join(os.homedir(), '.atom-build.json'), + path.join(os.homedir(), '.atom-build.cson'), + path.join(os.homedir(), '.atom-build.yml') + ].filter(fs.existsSync); return 0 < this.files.length; } diff --git a/spec/build-atomCommandName-spec.js b/spec/build-atomCommandName-spec.js index 68d33df9..ed3488cb 100644 --- a/spec/build-atomCommandName-spec.js +++ b/spec/build-atomCommandName-spec.js @@ -3,14 +3,18 @@ import fs from 'fs-extra'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('AtomCommandName', () => { + const originalHomedirFn = os.homedir; let directory = null; let workspaceElement = null; temp.track(); beforeEach(() => { + const createdHomeDir = temp.mkdirSync('atom-build-spec-home'); + os.homedir = () => createdHomeDir; directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })); atom.project.setPaths([ directory ]); @@ -33,6 +37,7 @@ describe('AtomCommandName', () => { }); afterEach(() => { + os.homedir = originalHomedirFn; fs.removeSync(directory); }); diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index 0143e2c3..ae479653 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -4,16 +4,20 @@ import _ from 'lodash'; import fs from 'fs-extra'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('Confirm', () => { let directory = null; let workspaceElement = null; const cat = process.platform === 'win32' ? 'type' : 'cat'; const waitTime = process.env.CI ? 2400 : 200; + const originalHomedirFn = os.homedir; temp.track(); beforeEach(() => { + const createdHomeDir = temp.mkdirSync('atom-build-spec-home'); + os.homedir = () => createdHomeDir; directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.setPaths([ directory ]); @@ -37,6 +41,7 @@ describe('Confirm', () => { afterEach(() => { fs.removeSync(directory); + os.homedir = originalHomedirFn; }); describe('when the text editor is modified', () => { diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index b2efcd04..f69f6fc2 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -4,6 +4,7 @@ import fs from 'fs-extra'; import path from 'path'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('Error Match', () => { const errorMatchAtomBuildFile = __dirname + '/fixture/.atom-build.error-match.json'; @@ -13,6 +14,7 @@ describe('Error Match', () => { const errorMatchMultiFirstAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-first.json'; const errorMatchLongOutputAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-long-output.json'; const errorMatchMultiMatcherAtomBuildFile = __dirname + '/fixture/.atom-build.error-match-multiple-errorMatch.json'; + const originalHomedirFn = os.homedir; let directory = null; let workspaceElement = null; @@ -21,6 +23,8 @@ describe('Error Match', () => { temp.track(); beforeEach(() => { + const createdHomeDir = temp.mkdirSync('atom-build-spec-home'); + os.homedir = () => createdHomeDir; directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + path.sep; atom.project.setPaths([ directory ]); @@ -46,6 +50,7 @@ describe('Error Match', () => { afterEach(() => { fs.removeSync(directory); + os.homedir = originalHomedirFn; }); describe('when error matcher is configured incorrectly', () => { diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index e21f3423..a37e35fe 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -4,14 +4,18 @@ import fs from 'fs-extra'; import path from 'path'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('Keymap', () => { + const originalHomedirFn = os.homedir; let directory = null; let workspaceElement = null; temp.track(); beforeEach(() => { + const createdHomeDir = temp.mkdirSync('atom-build-spec-home'); + os.homedir = () => createdHomeDir; directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + path.sep; atom.project.setPaths([ directory ]); @@ -34,6 +38,7 @@ describe('Keymap', () => { }); afterEach(() => { + os.homedir = originalHomedirFn; fs.removeSync(directory); }); diff --git a/spec/build-spec.js b/spec/build-spec.js index e5060e6e..149fa2f1 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -4,6 +4,7 @@ import fs from 'fs-extra'; import path from 'path'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('Build', () => { const goodAtomBuildfile = __dirname + '/fixture/.atom-build.json'; @@ -13,6 +14,7 @@ describe('Build', () => { const shTrueAtomBuildFile = __dirname + '/fixture/.atom-build.sh-true.json'; const shDefaultAtomBuildFile = __dirname + '/fixture/.atom-build.sh-default.json'; const syntaxErrorAtomBuildFile = __dirname + '/fixture/.atom-build.syntax-error.json'; + const originalHomedirFn = os.homedir; let directory = null; let workspaceElement = null; @@ -41,6 +43,11 @@ describe('Build', () => { }).then( (dir) => { directory = dir + path.sep; atom.project.setPaths([ directory ]); + return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home'); + }).then( (dir) => { + return specHelpers.vouch(fs.realpath, dir); + }).then( (dir) => { + os.homedir = () => dir; return atom.packages.activatePackage('build'); }); }); @@ -48,6 +55,7 @@ describe('Build', () => { afterEach(() => { fs.removeSync(directory); + os.homedir = originalHomedirFn; }); describe('when package is activated', () => { diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index a9a972c4..1a03fb7d 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -4,8 +4,10 @@ import _ from 'lodash'; import fs from 'fs-extra'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('Target', () => { + const originalHomedirFn = os.homedir; let directory = null; let workspaceElement = null; @@ -29,12 +31,18 @@ describe('Target', () => { }).then((dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); + return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home'); + }).then( (dir) => { + return specHelpers.vouch(fs.realpath, dir); + }).then( (dir) => { + os.homedir = () => dir; return atom.packages.activatePackage('build'); }); }); }); afterEach(() => { + os.homedir = originalHomedirFn; fs.removeSync(directory); }); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 1f256b7c..73af6577 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -3,8 +3,10 @@ import fs from 'fs-extra'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('BuildView', () => { + const originalHomedirFn = os.homedir; let directory = null; let workspaceElement = null; const sleep = (duration) => process.platform === 'win32' ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; @@ -35,12 +37,18 @@ describe('BuildView', () => { }).then( (dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); + return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home'); + }).then( (dir) => { + return specHelpers.vouch(fs.realpath, dir); + }).then( (dir) => { + os.homedir = () => dir; return atom.packages.activatePackage('build'); }); }); }); afterEach(() => { + os.homedir = originalHomedirFn; fs.removeSync(directory); }); diff --git a/spec/build-visible-spec.js b/spec/build-visible-spec.js index adcbecb6..e1fbef1e 100644 --- a/spec/build-visible-spec.js +++ b/spec/build-visible-spec.js @@ -3,11 +3,13 @@ import fs from 'fs-extra'; import temp from 'temp'; import specHelpers from 'atom-build-spec-helpers'; +import os from 'os'; describe('Visible', () => { let directory = null; let workspaceElement = null; const waitTime = process.env.CI ? 2400 : 200; + const originalHomedirFn = os.homedir; temp.track(); @@ -35,11 +37,17 @@ describe('Visible', () => { }).then( (dir) => { directory = dir + '/'; atom.project.setPaths([ directory ]); + return specHelpers.vouch(temp.mkdir, 'atom-build-spec-home'); + }).then( (dir) => { + return specHelpers.vouch(fs.realpath, dir); + }).then( (dir) => { + os.homedir = () => dir; }); }); }); afterEach(() => { + os.homedir = originalHomedirFn; fs.removeSync(directory); }); diff --git a/spec/custom-provider-spec.js b/spec/custom-provider-spec.js index bea13cbb..c44bf98f 100644 --- a/spec/custom-provider-spec.js +++ b/spec/custom-provider-spec.js @@ -3,14 +3,19 @@ import fs from 'fs-extra'; import temp from 'temp'; import CustomFile from '../lib/atom-build.js'; +import os from 'os'; describe('custom provider', () => { + const originalHomedirFn = os.homedir; let builder; let directory = null; + let createdHomeDir; temp.track(); beforeEach(() => { + createdHomeDir = temp.mkdirSync('atom-build-spec-home'); + os.homedir = () => createdHomeDir; directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })) + '/'; atom.project.setPaths([ directory ]); builder = new CustomFile(directory); @@ -18,14 +23,44 @@ describe('custom provider', () => { afterEach(() => { fs.removeSync(directory); + os.homedir = originalHomedirFn; }); - describe('when .atom-build.cson exists', () => { - it('it should be eligible targets', () => { - fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); + it('when there is no .atom-build config file in any elegible directory', () => { + expect(builder.isEligible()).toEqual(false); + }); + + describe('when .atom-build config is on home directory', () => { + it('should find json file in home directory', () => { + fs.writeFileSync(createdHomeDir + '/.atom-build.json', fs.readFileSync(__dirname + '/fixture/.atom-build.json')); + expect(builder.isEligible()).toEqual(true); + }); + it('should find cson file in home directory', () => { + fs.writeFileSync(createdHomeDir + '/.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); + expect(builder.isEligible()).toEqual(true); + }); + it('should find yml file in home directory', () => { + fs.writeFileSync(createdHomeDir + '/.atom-build.yml', fs.readFileSync(__dirname + '/fixture/.atom-build.yml')); + expect(builder.isEligible()).toEqual(true); + }); + }); + + describe('when .atom-build config is on project directory', () => { + it('should find json file in home directory', () => { + fs.writeFileSync(directory + '/.atom-build.json', fs.readFileSync(__dirname + '/fixture/.atom-build.json')); + expect(builder.isEligible()).toEqual(true); + }); + it('should find cson file in home directory', () => { + fs.writeFileSync(directory + '/.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); + expect(builder.isEligible()).toEqual(true); + }); + it('should find yml file in home directory', () => { + fs.writeFileSync(directory + '/.atom-build.yml', fs.readFileSync(__dirname + '/fixture/.atom-build.yml')); expect(builder.isEligible()).toEqual(true); }); + }); + describe('when .atom-build.cson exists', () => { it('it should provide targets', () => { fs.writeFileSync(directory + '.atom-build.cson', fs.readFileSync(__dirname + '/fixture/.atom-build.cson')); expect(builder.isEligible()).toEqual(true); @@ -45,11 +80,6 @@ describe('custom provider', () => { }); describe('when .atom-build.json exists', () => { - it('it should be eligible targets', () => { - fs.writeFileSync(`${directory}.atom-build.json`, fs.readFileSync(`${__dirname}/fixture/.atom-build.json`)); - expect(builder.isEligible()).toEqual(true); - }); - it('it should provide targets', () => { fs.writeFileSync(`${directory}.atom-build.json`, fs.readFileSync(`${__dirname}/fixture/.atom-build.json`)); expect(builder.isEligible()).toEqual(true); @@ -66,11 +96,6 @@ describe('custom provider', () => { }); describe('when .atom-build.yml exists', () => { - it('it should be eligible targets', () => { - fs.writeFileSync(`${directory}.atom-build.yml`, fs.readFileSync(`${__dirname}/fixture/.atom-build.yml`)); - expect(builder.isEligible()).toEqual(true); - }); - it('it should provide targets', () => { fs.writeFileSync(`${directory}.atom-build.yml`, fs.readFileSync(`${__dirname}/fixture/.atom-build.yml`)); expect(builder.isEligible()).toEqual(true); From 91eeb982ad83d1c6b356d98225bff0a1ccdde6b6 Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Thu, 25 Feb 2016 18:31:07 +0100 Subject: [PATCH 321/495] Updated appveyor CI methodology --- appveyor.yml | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d1912072..518c683b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,19 +1,25 @@ -environment: - nodejs_version: "5" - version: "{build}" -os: Windows Server 2012 R2 -test: off -deploy: off +platform: x64 + +branches: + only: + - master + +skip_tags: true + +environment: + APM_TEST_PACKAGES: + + matrix: + - ATOM_CHANNEL: stable + - ATOM_CHANNEL: beta install: - - appveyor DownloadFile https://atom.io/download/windows -FileName AtomSetup.exe - - AtomSetup.exe /silent + - ps: Install-Product node 5 build_script: - - cd %APPVEYOR_BUILD_FOLDER% - - SET PATH=%LOCALAPPDATA%\atom\bin;%PATH% - - apm clean - - apm install - - apm test \ No newline at end of file + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1')) + +test: off +deploy: off From 7fa505c91e1cc2b160905beb787b961f170242a1 Mon Sep 17 00:00:00 2001 From: Dmytro Kyrychuk Date: Thu, 25 Feb 2016 20:29:12 +0200 Subject: [PATCH 322/495] Implement pre-/post-build hooks If target has the "preBuild" attribute and it is a function, it will be called before the build. If "preBuild" returns a promise, build will be started after the promise resolution. "postBuild" hook is called upon child closed. "postBuild" receives a build status as an argument. --- lib/build.js | 10 +++ spec/build-hooks-spec.js | 110 ++++++++++++++++++++++++++++ spec/fixture/.atom-build.hooks.json | 6 ++ 3 files changed, 126 insertions(+) create mode 100644 spec/build-hooks-spec.js create mode 100644 spec/fixture/.atom-build.hooks.json diff --git a/lib/build.js b/lib/build.js index af201187..bddd4cc2 100644 --- a/lib/build.js +++ b/lib/build.js @@ -333,6 +333,12 @@ export default { throw new BuildError('Invalid build file.', 'No executable command specified.'); } + return Promise.resolve().then(() => { + if (target.preBuild && _.isFunction(target.preBuild)) { + return target.preBuild(); + } + }).then(() => target); + }).then(target => { const env = _.extend({}, process.env, target.env); _.forEach(env, (value, key, list) => { list[key] = this.replace(value, target.env); @@ -410,6 +416,10 @@ export default { GoogleAnalytics.sendEvent('build', 'failed'); } this.child = null; + + if (target.postBuild && _.isFunction(target.postBuild)) { + return target.postBuild(success); + } }); this.statusBarView && this.statusBarView.buildStarted(); diff --git a/spec/build-hooks-spec.js b/spec/build-hooks-spec.js new file mode 100644 index 00000000..215e6a0b --- /dev/null +++ b/spec/build-hooks-spec.js @@ -0,0 +1,110 @@ +'use babel'; + +import fs from 'fs-extra'; +import temp from 'temp'; +import specHelpers from 'atom-build-spec-helpers'; + +describe('Hooks', () => { + let directory = null; + let workspaceElement = null; + let target = null; + const commandName = 'build:hook-test:trigger-build'; + + function getBuildModule() { + return atom.packages.getLoadedPackage('build').mainModule; + } + + temp.track(); + + beforeEach(() => { + directory = fs.realpathSync(temp.mkdirSync({ prefix: 'atom-build-spec-' })); + atom.project.setPaths([ directory ]); + + atom.config.set('build.buildOnSave', false); + atom.config.set('build.panelVisibility', 'Toggle'); + atom.config.set('build.saveOnBuild', false); + atom.config.set('build.notificationOnRefresh', true); + + jasmine.unspy(window, 'setTimeout'); + jasmine.unspy(window, 'clearTimeout'); + + runs(() => { + workspaceElement = atom.views.getView(atom.workspace); + jasmine.attachToDOM(workspaceElement); + }); + + waitsForPromise(() => { + return atom.packages.activatePackage('build'); + }); + + runs(() => { + fs.writeFileSync(directory + '/.atom-build.json', fs.readFileSync(__dirname + '/fixture/.atom-build.hooks.json')); + }); + + waitsForPromise(() => specHelpers.refreshAwaitTargets()); + }); + + afterEach(() => { + fs.removeSync(directory); + }); + + it('should call preBuild', () => { + runs(() => { + target = getBuildModule().targets[directory].find(t => t.atomCommandName === commandName); + target.preBuild = () => {}; + spyOn(target, 'preBuild'); + + atom.commands.dispatch(workspaceElement, commandName); + }); + + waitsFor(() => { + return workspaceElement.querySelector('.build .title'); + }); + + runs(() => { + expect(target.preBuild).toHaveBeenCalled(); + }); + }); + + describe('postBuild', () => { + it('should be called with `true` as an argument when build succeded', () => { + runs(() => { + target = getBuildModule().targets[directory].find(t => t.atomCommandName === commandName); + target.postBuild = () => {}; + spyOn(target, 'postBuild'); + + atom.commands.dispatch(workspaceElement, commandName); + }); + + waitsFor(() => { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('success'); + }); + + runs(() => { + expect(target.postBuild).toHaveBeenCalledWith(true); + }); + }); + + it('should be called with `false` as an argument when build failed', () => { + runs(() => { + target = getBuildModule().targets[directory].find(t => t.atomCommandName === commandName); + target.postBuild = () => {}; + spyOn(target, 'postBuild'); + + target.args = ['1']; + + atom.commands.dispatch(workspaceElement, commandName); + }); + + waitsFor(() => { + return workspaceElement.querySelector('.build .title') && + workspaceElement.querySelector('.build .title').classList.contains('error'); + }); + + runs(() => { + expect(target.postBuild).toHaveBeenCalledWith(false); + }); + }); + }); +}); diff --git a/spec/fixture/.atom-build.hooks.json b/spec/fixture/.atom-build.hooks.json new file mode 100644 index 00000000..b60cd272 --- /dev/null +++ b/spec/fixture/.atom-build.hooks.json @@ -0,0 +1,6 @@ +{ + "cmd": "exit", + "args": ["0"], + "atomCommandName": "build:hook-test:trigger-build", + "sh": true +} From 2f32a8aa1463a3b8fa1cf89fca7c8a4168ded67d Mon Sep 17 00:00:00 2001 From: Alexander Olsson Date: Sun, 28 Feb 2016 22:08:46 +0100 Subject: [PATCH 323/495] Use Term.JS rather than custom output Term.JS is very capable of displaying output targeted at terminals in HTML. It supports a wide range of control characters making output display correctly. Advanced stuff such as full screen renderings work. There are two caveats with this implementation: * No longer underline and make links clickable when error matched. The short key still works, and it still scrolls the terminal to the correct location. * Since term.js hard break lines when terminal width is reached (regardless of occurance of newline char) it is difficult to find a matched text. The current implementation decreases the matched text until it finds a subset that matches. This may of course not be accurate at all times. But hopefully close enough. I think the two caveats are minor considering the reduced maintenance of this package and the immensely improved support for terminal based output. --- lib/build-view.js | 149 ++++++++++------ lib/build.js | 49 +++--- lib/error-matcher.js | 8 +- package.json | 1 - spec/build-atomCommandName-spec.js | 2 +- spec/build-confirm-spec.js | 2 +- spec/build-error-match-spec.js | 18 +- spec/build-keymap-spec.js | 16 +- spec/build-spec.js | 32 ++-- spec/build-targets-spec.js | 8 +- spec/build-view-spec.js | 89 +--------- spec/build-visible-spec.js | 166 +++++++++--------- spec/custom-provider-spec.js | 6 +- .../.atom-build.error-match-long-output.json | 2 +- ...build.error-match-multiple-errorMatch.json | 2 +- styles/build.less | 55 ++++-- 16 files changed, 287 insertions(+), 318 deletions(-) diff --git a/lib/build-view.js b/lib/build-view.js index ecef0ce9..bcdd8770 100644 --- a/lib/build-view.js +++ b/lib/build-view.js @@ -1,28 +1,79 @@ 'use babel'; -import _ from 'lodash'; import { View, $ } from 'atom-space-pen-views'; -import ansiUp from 'ansi_up'; import GoogleAnalytics from './google-analytics'; +import Terminal from 'term.js'; export default class BuildView extends View { - constructor() { - super(...arguments); + constructor(...args) { + super(...args); this.monocle = false; this.starttime = new Date(); - this.buffer = new Buffer(0); - this.links = []; + this.terminal = new Terminal({ + screenKeys: true, + convertEol: true, + termName: 'xterm-256color' + }); + this.terminal.getContent = function () { + return this.lines.reduce((m1, line) => m1 + line.reduce((m2, col) => m2 + col[1], '') + '\n', ''); + }; + this.terminal.open(this.output[0]); + this.destroyTerminal = ::(this.terminal).destroy; + this.terminal.destroy = this.terminal.destroySoon = () => {}; // This terminal will be open forever and reset when necessary + this.terminalEl = this.output.find('.terminal'); + this.terminalEl[0].terminal = this.terminal; // For testing purposes + + this.output[0].addEventListener('transitionend', ::this.resizeTerminal); + this.outputWidth = this.output.width(); + this.outputHeight = this.output.height(); + setInterval(::this.detectResize, 1000); this._setMonocleIcon(); - atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this)); - atom.config.observe('build.panelOrientation', this.orientationFromConfig.bind(this)); - atom.config.observe('build.monocleHeight', this.sizeFromConfig.bind(this)); - atom.config.observe('build.minimizedHeight', this.sizeFromConfig.bind(this)); - atom.config.observe('editor.fontFamily', this.fontFromConfig.bind(this)); - atom.config.observe('editor.fontSize', this.fontFromConfig.bind(this)); + atom.config.observe('build.panelVisibility', ::this.visibleFromConfig); + atom.config.observe('build.panelOrientation', ::this.orientationFromConfig); + atom.config.observe('build.monocleHeight', ::this.sizeFromConfig); + atom.config.observe('build.minimizedHeight', ::this.sizeFromConfig); + atom.config.observe('editor.fontFamily', ::this.fontFromConfig); + atom.config.observe('editor.fontSize', ::this.fontFromConfig); + + atom.commands.add('atom-workspace', 'build:toggle-panel', ::this.toggle); + } - atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this)); + destroy() { + this.destroyTerminal(); + } + + detectResize() { + if (!this.isAttached()) { + return; + } + if (this.outputWidth !== this.output.width() || this.outputHeight !== this.output.height()) { + this.resizeTerminal(); + this.outputWidth = this.output.width(); + this.outputHeight = this.output.height(); + } + } + + getFontGeometry() { + const o = $('
                  A
                  ') + .addClass('terminal') + .addClass('terminal-test') + .appendTo(this.output); + const w = o[0].getBoundingClientRect().width; + const h = o[0].getBoundingClientRect().height; + o.remove(); + return { w: w, h: h}; + } + + resizeTerminal() { + const { w, h } = this.getFontGeometry(); + this.terminal.resize(Math.floor((this.output.width() - 6) / w), Math.floor((this.output.height() - 6) / h)); // -6 for border of terminal + this.terminal.refresh(0, this.terminal.rows - 1); + } + + getContent() { + return this.terminal.getContent(); } static initialTimerText() { @@ -31,7 +82,7 @@ export default class BuildView extends View { static content() { this.div({ tabIndex: -1, class: 'build tool-panel panel-bottom native-key-bindings' }, () => { - this.div({ class: 'control-container pull-right opaque-hover' }, () => { + this.div({ class: 'control-container opaque-hover' }, () => { this.button({ class: 'btn btn-default icon icon-x', click: 'close' }); this.button({ class: 'btn btn-default icon icon-chevron-up', outlet: 'monocleButton', click: 'toggleMonocle' }); this.button({ class: 'btn btn-default icon icon-trashcan new-row', click: 'clearOutput' }); @@ -42,6 +93,7 @@ export default class BuildView extends View { }); }); + this.div({ class: 'panel-heading', outlet: 'heading' }); this.div({ class: 'output panel-body', outlet: 'output' }); }); } @@ -68,7 +120,7 @@ export default class BuildView extends View { this.panel = addfn[orientation].call(atom.workspace, { item: this }); this.sizeFromConfig(); this.fontFromConfig(); - this.output.scrollTop(this.output[0].scrollHeight); + this.resizeTerminal(); } detach(force) { @@ -99,7 +151,7 @@ export default class BuildView extends View { switch (val) { case 'Toggle': case 'Show on Error': - if (!this.title.hasClass('error')) { + if (!this.terminalEl.hasClass('error')) { this.detach(); } break; @@ -111,19 +163,19 @@ export default class BuildView extends View { this.detach(true); if (isVisible) { this.attach(); - this._setMonocleIcon(); } + this._setMonocleIcon(); } reset() { clearTimeout(this.titleTimer); this.buildTimer.text(BuildView.initialTimerText()); this.titleTimer = 0; - this.clearOutput(); + this.terminal.reset(); - this.title.removeClass('success error'); this.gear.removeClass('spin spin-flash'); - this.removeClass('success error'); + this.heading.removeClass('success error'); + this.title.removeClass('success error'); this.detach(); } @@ -143,9 +195,7 @@ export default class BuildView extends View { } clearOutput() { - this.buffer = new Buffer(0); - this.links = []; - this.output.empty(); + this.terminal.reset(); } build() { @@ -198,6 +248,9 @@ export default class BuildView extends View { this._setMonocleIcon(); } + setHeading(heading) { + this.heading.text(heading); + } buildStarted() { this.starttime = new Date(); this.reset(); @@ -226,49 +279,29 @@ export default class BuildView extends View { finalizeBuild(success) { this.title.addClass(success ? 'success' : 'error'); - this.addClass(success ? 'success' : 'error'); + this.heading.addClass(success ? 'success' : 'error'); this.gear.removeClass('spin spin-flash'); clearTimeout(this.titleTimer); } - _render() { - let string = _.escape(this.buffer.toString('utf8')); - this.links.forEach((link) => { - const replaceRegex = new RegExp(_.escapeRegExp(_.escape(link.text)), 'g'); - string = string.replace(replaceRegex, '' + _.escape(link.text) + ''); - }); - this.output.html(ansiUp.ansi_to_html(string)); - this.output.find('a').on('click', (event) => { - this.links.find(l => l.id === event.currentTarget.id).onClick(); - }); - } - - append(data) { - const shouldScroll = (this.output[0].scrollHeight - this.output[0].scrollTop === this.output[0].offsetHeight); - this.buffer = Buffer.concat([ this.buffer, Buffer.isBuffer(data) ? data : new Buffer(data) ]); - this._render(); - if (shouldScroll) { - this.output.scrollTop(this.output[0].scrollHeight); + scrollTo(text) { + const content = this.getContent(); + let endPos = -1; + let curPos = text.length; + // We need to decrese the size of `text` until we find a match. This is because + // terminal will insert line breaks ('\r\n') when width of terminal is reached. + // It may have been that the middle of a matched error is on a line break. + while (-1 === endPos && curPos > 0) { + endPos = content.indexOf(text.substring(0, curPos--)); } - } - link(text, id, onClick) { - if (this.links.find(l => l.text === text)) { + if (curPos === 0) { + // No match - which is weird. Oh well - rather be defensive return; } - this.links.push({ - id: id, - text: text, - onClick: onClick - }); - this._render(); - } - - scrollTo(id) { - const position = this.output.find('#' + id).position(); - if (position) { - this.output.scrollTop(position.top + this.output.scrollTop()); - } + const row = content.slice(0, endPos).split('\n').length; + this.terminal.ydisp = 0; + this.terminal.scrollDisp(row - 1); } } diff --git a/lib/build.js b/lib/build.js index af201187..754a104b 100644 --- a/lib/build.js +++ b/lib/build.js @@ -37,9 +37,6 @@ export default { this.activeTarget = {}; this.targetsLoading = {}; this.targetsSubscriptions = {}; - - this.stdout = new Buffer(0); - this.stderr = new Buffer(0); this.errorMatcher = new ErrorMatcher(); atom.commands.add('atom-workspace', 'build:refresh-targets', () => this.refreshTargets()); @@ -71,13 +68,8 @@ export default { atom.notifications.addError('Error matching failed!', { detail: message }); }); - this.errorMatcher.on('matched', (id) => { - this.buildView.scrollTo(id); - }); - - this.errorMatcher.on('match', (text, id) => { - const callback = this.errorMatcher.goto.bind(this.errorMatcher, id); - this.buildView.link(text, id, callback); + this.errorMatcher.on('matched', (match) => { + this.buildView.scrollTo(match[0]); }); atom.packages.onDidActivateInitialPackages(() => this.refreshTargets()); @@ -107,6 +99,7 @@ export default { } this.statusBarView && this.statusBarView.destroy(); + this.buildView && this.buildView.destroy(); clearTimeout(this.finishedTimer); }, @@ -263,10 +256,11 @@ export default { this.targetsView = new TargetsView(); if (this.targetsLoading[p]) { - return this.targetsView.setLoading('Loading project build targets\u2026'); + this.targetsView.setLoading('Loading project build targets\u2026'); + } else { + this.fillTargets(); } - this.fillTargets(); this.targetsView.awaitSelection().then((newTarget) => { this.activeTarget[p] = newTarget; this.updateStatusBar(); @@ -359,33 +353,30 @@ export default { ); } - this.stdout = new Buffer(0); - this.child.stdout.on('data', (buffer) => { - this.stdout = Buffer.concat([ this.stdout, buffer ]); - this.buildView.append(buffer); - }); - - this.stderr = new Buffer(0); - this.child.stderr.on('data', (buffer) => { - this.stderr = Buffer.concat([ this.stderr, buffer ]); - this.buildView.append(buffer); - }); + let stdout = ''; + let stderr = ''; + this.child.stdout.setEncoding('utf8'); + this.child.stderr.setEncoding('utf8'); + this.child.stdout.on('data', d => stdout += d); + this.child.stderr.on('data', d => stderr += d); + this.child.stdout.pipe(this.buildView.terminal); + this.child.stderr.pipe(this.buildView.terminal); this.child.on('error', (err) => { - this.buildView.append((target.sh ? 'Unable to execute with sh: ' : 'Unable to execute: ') + exec + '\n'); + this.buildView.terminal.write((target.sh ? 'Unable to execute with shell: ' : 'Unable to execute: ') + exec + '\n'); if (/\s/.test(exec) && !target.sh) { - this.buildView.append('`cmd` cannot contain space. Use `args` for arguments.\n'); + this.buildView.terminal.write('`cmd` cannot contain space. Use `args` for arguments.\n'); } if ('ENOENT' === err.code) { - this.buildView.append('Make sure `cmd` and `cwd` exists and have correct access permissions.\n'); - this.buildView.append(`Build finds binaries in these folders: ${process.env.PATH}\n`); + this.buildView.terminal.write(`Make sure cmd:'${exec}' and cwd:'${cwd}' exists and have correct access permissions.\n`); + this.buildView.terminal.write(`Binaries are found in these folders: ${process.env.PATH}\n`); } }); this.child.on('close', (exitCode) => { - this.errorMatcher.set(target.errorMatch, cwd, this.buildView.output.text()); + this.errorMatcher.set(target.errorMatch, cwd, stdout + stderr); let success = (0 === exitCode); if (atom.config.get('build.matchedErrorFailsBuild')) { @@ -414,7 +405,7 @@ export default { this.statusBarView && this.statusBarView.buildStarted(); this.buildView.buildStarted(); - this.buildView.append([ (target.sh ? 'Executing with sh:' : 'Executing:'), exec, ...args, '\n'].join(' ')); + this.buildView.setHeading([ (target.sh ? `${shCmd} ${shCmdArg} ${exec}` : exec ), ...args, '\n'].join(' ')); }).catch((err) => { if (err instanceof BuildError) { if (source === 'save') { diff --git a/lib/error-matcher.js b/lib/error-matcher.js index 6c831425..74b1c19d 100644 --- a/lib/error-matcher.js +++ b/lib/error-matcher.js @@ -17,8 +17,8 @@ export default class ErrorMatcher extends EventEmitter { this.currentMatch = []; this.firstMatchId = null; - atom.commands.add('atom-workspace', 'build:error-match', this.match.bind(this)); - atom.commands.add('atom-workspace', 'build:error-match-first', this.matchFirst.bind(this)); + atom.commands.add('atom-workspace', 'build:error-match', ::this.match); + atom.commands.add('atom-workspace', 'build:error-match-first', ::this.matchFirst); } _gotoNext() { @@ -62,7 +62,7 @@ export default class ErrorMatcher extends EventEmitter { initialColumn: col, searchAllPanes: true }); - this.emit('matched', match.id); + this.emit('matched', match); }); } @@ -80,8 +80,6 @@ export default class ErrorMatcher extends EventEmitter { this.currentMatch.sort((a, b) => a.index - b.index); this.firstMatchId = (this.currentMatch.length > 0) ? this.currentMatch[0].id : null; - - this.currentMatch.forEach(match => this.emit('match', match[0], match.id)); } set(regex, cwd, output) { diff --git a/package.json b/package.json index a3513054..981c9bfa 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "atom": ">=0.50.0" }, "dependencies": { - "ansi_up": "^1.3.0", "atom-space-pen-views": "^2.0.3", "cross-spawn-async": "^2.1.8", "cson-parser": "^1.3.0", diff --git a/spec/build-atomCommandName-spec.js b/spec/build-atomCommandName-spec.js index ed3488cb..986a7721 100644 --- a/spec/build-atomCommandName-spec.js +++ b/spec/build-atomCommandName-spec.js @@ -59,7 +59,7 @@ describe('AtomCommandName', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); }); diff --git a/spec/build-confirm-spec.js b/spec/build-confirm-spec.js index ae479653..92b65a7c 100644 --- a/spec/build-confirm-spec.js +++ b/spec/build-confirm-spec.js @@ -133,7 +133,7 @@ describe('Confirm', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); diff --git a/spec/build-error-match-spec.js b/spec/build-error-match-spec.js index f69f6fc2..19c1a680 100644 --- a/spec/build-error-match-spec.js +++ b/spec/build-error-match-spec.js @@ -299,9 +299,9 @@ describe('Error Match', () => { }); }); - it('should open the the file even if tool gives absolute path', () => { + it('should open the file even if tool gives absolute path', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo __' + directory + '.atom-build.json__ && return 1', + cmd: 'echo __' + directory + '.atom-build.json__ && exit 1', errorMatch: '__(?.+)__' })); @@ -421,22 +421,21 @@ describe('Error Match', () => { }); waits(waitTime); - let firstScrollTop; runs(() => { - firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; + expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(waitTime); runs(() => { - expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); + expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(12); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(waitTime); runs(() => { /* Should wrap around to first match */ - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); + expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6); }); }); @@ -458,21 +457,20 @@ describe('Error Match', () => { }); waits(waitTime); - let firstScrollTop; runs(() => { - firstScrollTop = workspaceElement.querySelector('.build .output').scrollTop; + expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6); atom.commands.dispatch(workspaceElement, 'build:error-match'); }); waits(waitTime); runs(() => { - expect(workspaceElement.querySelector('.build .output').scrollTop).toBeGreaterThan(firstScrollTop); + expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(12); atom.commands.dispatch(workspaceElement, 'build:error-match-first'); }); waits(waitTime); runs(() => { - expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(firstScrollTop); + expect(workspaceElement.querySelector('.terminal').terminal.ydisp).toEqual(6); }); }); diff --git a/spec/build-keymap-spec.js b/spec/build-keymap-spec.js index a37e35fe..1a84b764 100644 --- a/spec/build-keymap-spec.js +++ b/spec/build-keymap-spec.js @@ -65,7 +65,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); @@ -83,7 +83,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/keymapped/); }); }); @@ -109,7 +109,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); @@ -127,7 +127,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/keymapped/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); @@ -145,7 +145,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); }); }); @@ -172,7 +172,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); }); waitsFor(() => { @@ -189,7 +189,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/keymapped/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/keymapped/); atom.commands.dispatch(workspaceElement, 'build:toggle-panel'); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ name: 'The default build', @@ -226,7 +226,7 @@ describe('Keymap', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/ctrl-x new file/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/ctrl-x new file/); }); }); }); diff --git a/spec/build-spec.js b/spec/build-spec.js index 149fa2f1..db0baa1a 100644 --- a/spec/build-spec.js +++ b/spec/build-spec.js @@ -18,8 +18,10 @@ describe('Build', () => { let directory = null; let workspaceElement = null; - const sleep = (duration) => process.platform === 'win32' ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; - const cat = () => process.platform === 'win32' ? 'type' : 'cat'; + const isWin = process.platform === 'win32'; + const sleep = (duration) => isWin ? `ping 127.0.0.1 -n ${duration} > NUL` : `sleep ${duration}`; + const cat = () => isWin ? 'type' : 'cat'; + const shellCmd = isWin ? 'cmd /C' : '/bin/sh -c'; const waitTime = process.env.CI ? 2400 : 200; temp.track(); @@ -83,7 +85,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Very bad\.\.\./); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Very bad\.\.\./); }); }); @@ -121,7 +123,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Building, this will take some time.../); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Building, this will take some time.../); expect(workspaceElement.querySelector('.build .title .icon-gear').classList.contains('spin')).toBe(true); atom.commands.dispatch(workspaceElement, 'build:stop'); }); @@ -207,7 +209,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"args":\[".atom-build.json"\]/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"args":\[".atom-build.json"\]/); }); }); @@ -227,7 +229,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Good news, everyone!/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Good news, everyone!/); }); }); @@ -247,7 +249,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing with sh:/); + expect(workspaceElement.querySelector('.build .panel-heading').textContent).toMatch(new RegExp(`^${shellCmd}`)); }); }); @@ -269,7 +271,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing:/); + expect(workspaceElement.querySelector('.build .panel-heading').textContent).toMatch(/^echo/); }); }); @@ -289,7 +291,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Executing with sh:/); + expect(workspaceElement.querySelector('.build .panel-heading').textContent).toMatch(new RegExp(`^${shellCmd}`)); }); }); @@ -331,7 +333,7 @@ describe('Build', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/first/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/first/); }); waitsFor(() => { @@ -356,7 +358,7 @@ describe('Build', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/second/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/second/); }); }); }); @@ -384,7 +386,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - const output = workspaceElement.querySelector('.build .output').textContent; + const output = workspaceElement.querySelector('.terminal').terminal.getContent().replace(/\n/g, ''); expect(output.indexOf('PROJECT_PATH=' + directory.substring(0, -1))).not.toBe(-1); expect(output.indexOf('FILE_ACTIVE=' + directory + '.atom-build.json')).not.toBe(-1); expect(output.indexOf('FROM_ENV=' + directory + '.atom-build.json')).not.toBe(-1); @@ -422,7 +424,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/Surprising is the passing of time but not so, as the time of passing/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/Surprising is the passing of time but not so, as the time of passing/); }); }); @@ -502,7 +504,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"args":\[".atom-build.json"\]/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"args":\[".atom-build.json"\]/); }); }); @@ -531,7 +533,7 @@ describe('Build', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/"args":\[".atom-build.json"\]/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"args":\[".atom-build.json"\]/); }); }); }); diff --git a/spec/build-targets-spec.js b/spec/build-targets-spec.js index 1a03fb7d..1d6a7960 100644 --- a/spec/build-targets-spec.js +++ b/spec/build-targets-spec.js @@ -117,7 +117,7 @@ describe('Target', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); }); }); @@ -138,7 +138,7 @@ describe('Target', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/default/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/default/); }); }); @@ -175,7 +175,7 @@ describe('Target', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/customized/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/); atom.commands.dispatch(workspaceElement.querySelector('.build'), 'build:stop'); }); @@ -193,7 +193,7 @@ describe('Target', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/customized/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/customized/); }); }); }); diff --git a/spec/build-view-spec.js b/spec/build-view-spec.js index 73af6577..2044763a 100644 --- a/spec/build-view-spec.js +++ b/spec/build-view-spec.js @@ -53,27 +53,6 @@ describe('BuildView', () => { }); describe('when output from build command should be viewed', () => { - it('should color output according to ansi escape codes', () => { - if (process.platform === 'win32') return; - - fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'printf "\\033[31mHello\\e[0m World"' - })); - - waitsForPromise(() => specHelpers.refreshAwaitTargets()); - - runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - - waitsFor(() => { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(() => { - expect(workspaceElement.querySelector('.build .output > span').style.color.match(/\d+/g)).toEqual([ '187', '0', '0' ]); - }); - }); - it('should output data even if no line break exists', () => { fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ cmd: 'node', @@ -91,32 +70,7 @@ describe('BuildView', () => { }); runs(() => { - expect(workspaceElement.querySelector('.build .output').textContent).toMatch(/data without linebreak/); - }); - }); - - it('should only break the line when an actual newline character appears', () => { - fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'node', - args: [ '-e', 'process.stdout.write(\'same\'); setTimeout(function() { process.stdout.write(\' line\\n\') }, 200);' ], - sh: false - })); - - waitsForPromise(() => specHelpers.refreshAwaitTargets()); - - runs(() => atom.commands.dispatch(workspaceElement, 'build:trigger')); - - waitsFor(() => { - return workspaceElement.querySelector('.build .title') && - workspaceElement.querySelector('.build .title').classList.contains('success'); - }); - - runs(() => { - const el = workspaceElement.querySelector('.build .output'); - /* Now we expect one line for the 'Executing...' row, one for the actual output and an empty one at the end. */ - const lines = el.textContent.split('\n'); - expect(lines.length).toEqual(3); - expect(lines[1]).toEqual('same line'); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/data without linebreak/); }); }); @@ -124,7 +78,7 @@ describe('BuildView', () => { expect(workspaceElement.querySelector('.build')).not.toExist(); fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({ - cmd: 'echo ""' + cmd: 'echo ""' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -138,7 +92,7 @@ describe('BuildView', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.build .output').innerHTML).toMatch(/<script type="text\/javascript">alert\('XSS!'\)<\/script>/); + expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/"' + cmd: 'echo ""' })); waitsForPromise(() => specHelpers.refreshAwaitTargets()); @@ -93,7 +93,7 @@ describe('BuildView', () => { runs(() => { expect(workspaceElement.querySelector('.build')).toExist(); - expect(workspaceElement.querySelector('.terminal').terminal.getContent()).toMatch(/